6 RAS Assembles Rune Assembly into a rune object file. Rune assembly
7 consists of any number of lines of code in the following format:
9 [label:] directive/opcode additional_spec
13 Labels must start with a alpha character (a-z, A-Z, '@', '_', or '.'),
14 and may contain a-z, A-Z, 0-9, '@', '_', or '.'.
16 Labels are local if not exported via .library or .public. Be sure
17 to be in the correct section when importing/exporting symbols.
19 Labels beginning with '.' are always local and may not be imported
24 A RAS assembly file may contain '#' style comments (comment to
25 end-of-line). Any amount of whitespace may separate elements of the
26 line (minimum one character of whitespace if no label is present).
30 RAS contains a simple expression parser which is able to collect
31 symbols, generate relocation information, and perform arithmatic.
32 RAS does not distinguish between signed and unsigned storage,
33 calculates are performed with signed arithmatic and truncated to fit.
35 binary operators: + - * / & | ^
37 binary conditionals: < <= == > >= !=
39 unary operators: + - ! ~
41 also: parenthesization (exp), and array specifications in certain
44 types: int{8, 16, 32, 64, 128, 256, 512}, float{32, 64, 128},
45 implied by context. Strings are interpreted as a
46 zero-terminated array of bytes.
48 Alignments, element counts, and addresses are limited
51 specials: .ORG - The current origin (as of the start of
52 the line), will generate a relocation
53 in a relative section. Identical to using
54 a label: defined on that same line.
56 .SECBEG - Beginning of current section.
59 .SECBEG(sect) - Beginning of specified section.
62 .SECEND - End of current section.
65 .SECEND(sect) - End of specified section.
68 NOTE: Beginning/End of section represents
69 the consolidated beginning and
70 consolidated ending post-link.
74 General C-style strtoq() parsing is accepted, so generally RAS
75 will parse decimal unless you specify a '0' octal prefix or '0x'
78 Floating point values are encoded using machine-independent
79 RUNE FP formats (which are base-2) and will be converted to
80 native formats by the translator.
82 Use of smaller (or longer) extension words in instructions.
84 Language emitters can place data and code in non-default sections
85 to optimize the use of shorter extension words. This means that
86 a program can use e.g. 16-bit offsetes for data accesses even if
87 the program defines more than 64KB of data, with proper use of
92 All emitted Rune code should be endian-independent, meaning that
93 proper data and structure layout typing should be used so the loader
94 can translate the program between endian architectures. Instructions
95 nominally load and store data in the native endian of the target,
96 which is not known until the program is actually run on that target.
97 Rune contains instructions for properly converting between types
98 and for loading and storing data with a particular endianess when
101 Register renaming, automatic spill, and automatic library %db caching.
103 Code emitters can use generic register specifications, e.g. '%r23',
104 or specific register specifications such as '%rb3'. When generic
105 specifications are used, RAS will automatically assign the proper
106 register and will automatically spill and unspill registers if it
107 runs out. Simple code emitters do not have to try to optimize
108 register use. Register #1 for all register domains is reserved
109 by RAS for the spill code if generic register specifications are
112 RAS will automatically optimize and cache library bases for libraries
113 specified in instructions. If you generate an instruction in
116 move.l %r23,LIBFUBAR:Counter
118 then RAS will cache the library base pointer in a pointer register
119 and generate something like:
121 (cache LIBFUBAR's base pointer in %p1)
122 move.l %r23,LIBFUBAR:Counter(%p1)
125 RAS will automatically generate vector specifications for library
126 procedures defined with .lproc and convert LCALL specifications to
127 the appropriate vector relocation. For example:
131 will be converted to something like:
133 (cache LIBSYS's base pointer in %p1)
134 lcall *LIBSYS:read(%p1)
136 These features can be used to access code and data from any library.
140 The code emitter may manually use the negative frame space for
141 any variable storage for which the address of the storage is NOT
142 taken. The negative frame space is used by later passes for
143 registerization optimizations.
145 Code emitters may place registerizable elements in the negative
146 frame space and must place unregisterizable elements in the positive
147 frame space. These elements must be accessed by the target procedure
148 the same way (but using %ap-relative instead of %fp-relative
149 accesses), and the argument structure must specify at least the
150 negative frame space offsets (and should specify all positive frame
151 space elements up to any var-args continuation).
153 RAS will match up these accesses to guarantee consistency and can
154 even handle caching a negative-frame-space argument in a register
155 across an entire call/return sequence.
157 Branch consolidation, extension selection
159 RAS will consolidate branches to unconditional branches or jumps
160 and remove dead code in code sections unless the 'noopt'
161 (no-optimize) flag is specified.
163 RAS will select the best-fit extension width for local branches,
164 which can sometimes lead to having to take several passes on the
167 RAS leaves major optimizations for later.
171 All sections are distinguished by library and name. The actual
172 section name winds up being "library:name".
174 Elements making up each distinct section are combined together,
175 ordered by {addr8, addr16, addr32, addr64}. bss follows data within
176 each addr-ordered subsection. Note that each library has distinct
177 section names so each library can control the addressing modes and
178 extension widths used within it to access library-specific data and
181 The final linker pass will collect distinct sections together in
182 a final layout for the program, potentially compacting the code and
183 data represented by multiple libraries into the same page.
185 The linker will further order abs sections according to their origin.
186 Most programs are fully relocatable, but pointer registers and storage
187 contains absolute addresses so we can't really simulate a fork()
188 without real process separation.
190 (II) Rune Assembly Pseudo-ops
194 Sets the default library name for section directives. Can be
195 overridden by individual section directives.
197 .section [lib:]name, type[, flags][, align[, filler]]
198 .code [[lib:]name] (section [name], code, addrXX)
199 .code16 [[lib:]name] (section [name], code, addr16)
200 .code32 [[lib:]name] (section [name], code, addr32)
201 .code64 [[lib:]name] (section [name], code, addr64)
202 .bss [[lib:]name] (section [name], data, bss, reorderok, addrXX)
203 .bss8 [[lib:]name] (section [name], data, bss, reorderok, addr8)
204 .bss16 [[lib:]name] (section [name], data, bss, reorderok, addr16)
205 .bss32 [[lib:]name] (section [name], data, bss, reorderok, addr32)
206 .bss64 [[lib:]name] (section [name], data, bss, reorderok, addr64)
207 .data [[lib:]name] (section [name], data, reorderok, addrXX)
208 .data8 [[lib:]name] (section [name], data, reorderok, addr8)
209 .data16 [[lib:]name] (section [name], data, reorderok, addr16)
210 .data32 [[lib:]name] (section [name], data, reorderok, addr32)
211 .data64 [[lib:]name] (section [name], data, ro, reorderok, addr64)
212 .rodata [[lib:]name] (section [name], data, ro, reorderok, addrXX)
213 .rodata8 [[lib:]name] (section [name], data, ro, reorderok, addr8)
214 .rodata16 [[lib:]name] (section [name], data, ro, reorderok, addr16)
215 .rodata32 [[lib:]name] (section [name], data, ro, reorderok, addr32)
216 .rodata64 [[lib:]name] (section [name], data, ro, reorderok, addr64)
218 Generate a section. All elements of a file across any number of
219 objects belonging to the same section will be collected together
220 in the final output and by the linker when linking multiple objects
223 name - A quoted section name. If not specified the name will
224 default to 'code', or 'data' depending on the directive
225 (NOTE: name must be specified for the .section directive).
227 type - code indicates a code section
228 data indicates a data section
230 flags - nogen generate for offset info only, generates no
231 output. The bss type is the same as
234 bss indicates a bss section. Generates no output.
236 addr8 Accessible with 8-bit relative addressing.
237 addr16 Accessible with 16-bit relative addressing.
238 addr32 Accessible with 32-bit relative addressing.
239 addr64 Accessible with 64-bit relative addressing.
241 abs indicates access to this section is via
242 absolute addressing. By default access is
243 always via %db-relative or %pc-relative
244 addressing depending on whether it is a
245 data section or code section.
247 reorderok Indicates that data layouts (e.g. directives
248 like .int32) can be reordered together to
249 reduce the number of structural relocations
252 noreorder Indicates that data layouts cannot be
257 strict Strictly enforce the read-only flag, prevents
258 combining rw and ro sections together within
261 align - A number indicating section alignment. The section
262 will be positioned to the specified alignment at the
263 beginning and padded to the specified alignment at
264 the end. Alignment must be a power of 2.
266 The largest alignment specified for the section or within
267 the section also becomes the section alignment. Data
268 and code directives also automatically generate a starting
271 NOTE: .code sections default to 2-byte alignment with a NOP
272 instruction as auto filler and 8/16/32/64-bit addressing
273 based on arguments to RAS (default is usually 32-bit
276 .code16, .code32, and .code64 defines sections whos symbols
277 will be accessed with 16, 32, or 64-bit addressing.
279 .data sections default to 1-byte alignment with zero for
280 the filler and 8/16/32/64-bit addressing based on arguments
281 to RAS (default is usually 32-bit addressing).
283 .data16, .data32, and .data64 defines sections whos symbols
284 will be accessed with 16, 32, or 64-bit addressing.
286 Assembly instructions must still specify absolute or relative
287 addressing. For example, SYMBOL(%pc) indicates pc-relative
288 addressing, SYMBOL(%db) indicates db-relative addressing.
290 .byte [exp [, exp]*] (same as .int8)
291 .word [exp [, exp]*] (same as .int16)
292 .long [exp [, exp]*] (same as .int32)
293 .quad [exp [, exp]*] (same as .int64)
295 .float* [exp [, exp]*]
297 Allocate zero or more data elements of the specified size. These
298 directives automatically perform a starting alignment of the native
299 size (even with no data elements).
301 The .int and .float directives must be suffixed with the number of
302 bits (in powers of 2 >= 8), for example .int8, and may also be
303 further suffixed with 'le' or 'be' for little-endian or big-endian.
306 If endian is not being forced, a structural relocation is associated
307 with the data for endian-conversion purposes.
309 If reordering is allowed,
313 Allocate the specified number of bytes of unstructured space.
317 Generate a value for a label. Equates should nominally be specified
318 in the appropriate section so the assembler knows how wide an
319 extension word it should embed in the code utilizing the symbol
320 if used for addressing or if relocations are present.
322 When no relocations are present the most compact form possible will
323 be used and the section is ignored. This will generally be the case
324 for immediate constants and pc-relative offsets.
328 Generate a library symbol for the specified library name. Library
329 names are typically prefixed with an '@LIB', e.g. @LIBSYS,
330 distinguishing them from normal variable names.
332 .align align [, filler]
334 Align the current origin to the specified value padding with the
335 specified filler, and set the default filler for the current
338 If no filler is specified, the current default filler for the
341 .fill element_size[, elements[, value]]
342 .fill structure[, elements][, { value, value, ... }]
344 Fill an array[elements] of element_size entities with the value.
345 If not specified, the current filler is used. In structure mode
346 the values making up the structure can be specified and the
347 structure will be repeated <elements> times. If <elements> is
348 not specified, one copy is loaded.
350 Also associates a structural relocation with the fill area.
352 .zero element_size[, elements]
353 .zero structure[, elements]
355 Fill an array[elements] of element_size entities with the value 0.
357 In structure mode a structural relocation is associated with the
358 zerod storage for endian relocation purposes.
362 Set the origin, typically <exp> is a constant. Only allowed
363 in absolute sections. Origins may not reverse-index within the
364 section and the linker will fail if origin ranges for absolute
365 sections overlap. Not recommended.
367 .public [label [, label]*]
368 .library [label [, label]*]
370 Specify the scope of labels that may be used in the assembly file.
371 This can be done anywhere in the assembly file. Be sure to specify
372 this direction in the correct section so the correct address mode
373 and/or extension word length is generated for instructions.
375 .struct { [ [id:]element_size[:offset] [, [id:]element_size[:offset]]* ] }
377 Associate a structure with a label. The directive must be labeled.
378 The structure may extend over several lines of assembly (successive
379 lines should be indented but not repeat the directive, until '}').
381 This creates structural relocation information in the object file
382 for endian conversion purposes.
384 Element sizes may be postfixed with '.le' or '.be' for little-endian
385 and big-endian if you desire the data to be formatted in a particular
386 way and not subject to automatic endian conversions by the
389 element_size is defined as the element size as a constant,
390 or a structure label. element_size can be postfixed with
391 an array specification [ exp ] where exp is a constant.
393 .prototype { struct_spec } ( struct_spec [...:offset] )
395 Associate a prototype with a label. The directive must be labeled
396 and structural elements must define appropriate negative and
397 positive frame-space offsets for elements. A var-args procedure
398 specifies an additional '...' and supplies the positive frame-space
399 offset that begins the variable arguments section.
401 This creates prototype relocation information in the object file
402 for procedural argument and return value specifications for
403 procoedures. Prototype relocations are basically the same as
404 a pair of structural relocations.
406 Negative frame-space elements can be optimized by later passes to
407 be passed and returned in machine registers. Note that var-args
408 elements are always positive-frame-space elements.
411 .lproc vector, prototype
414 Specify a procedure entry point (label on left). If this is to be
415 a library function, use .lproc to create a library function entry
416 point with the specified vector number. You may specify an optional
417 structure for return values (void assumed if none) and MUST specify
418 a structure for any arguments. This will create a structural
419 relocation for the procedure which allows later Rune passes to
420 optimize calls and returns for register-passing
422 You then lay the code out for the procedure, and finish-up with a
423 .end directive or another .proc/.lproc directive. Procedures cannot
426 RAS optimizes generic register specifications, spills, negative
427 frame space, and other procedural elements within the bounds of
428 the procedure specification.
430 RLD will generate the library's vector table
434 Generate a CATCH relocation with a target label. This does not
435 generate any actual code, but supplies information to the thread
436 manager to aid in RAISE handling. Any code after a .catch directive,
437 up until the next .catch or the end of the procedure, belongs to this
438 catch relocation. If a RAISE is executed or chained up from a
439 subroutine, code flow will jump to the target label.
441 RAISEd exceptions can unwind recursively. If an unhandled exception
442 occurs within a call, or the exception is handled but the RAISE
443 is chained upward, the return-from-procedure will chain to the
444 active catch label at the return pc instead of returning normally.
446 The huge advantage of .catch / RAISE in Rune is that all code handling
447 for a RAISE is out-of-band, leaving critical code paths untouched
448 including along procedural return paths.
450 Normal instructions do NOT generate RAISEs. Actual hard exceptions
451 such as a divide by zero or a memory fault is NOT considered to be
452 a RAISE. The mechanism is meant for explicit exception handling
453 and not for broken instructions. In otherwords, language emitters
454 can avoid having to generate unwind information for an exception
455 that might happen at any point in the instruction stream or if the
456 target procedure in a call is known to not generate any possible
459 Language emitters generally use .catch relocations so they can
460 generate code to unwind semantic levels and to test and execute
461 exception handling code. The Rune language uses this generously
462 to generate unwinding code either for explicit RAISE instructions
463 executed within a procedure or to unwind state if a procedure call
466 Note that later passes may be able to optimize out large portions
467 of any unwinding code you generate if it is determined to be
470 (III) Rune Assembly Op-codes
472 See insn.txt. Generally speaking when laying out op-codes you must
473 also specify absolute or relative-addressing by using the appropriate
474 indirect register specification. Constants can be expressions (including
475 with parenthesis), and extra spaces in the additional-spec section are
476 allowed. RAS distinguishes between register and non-register
477 parenthesized elements by looking for the '%' prefix on register names.