xref: /plan9-contrib/sys/doc/asm.ms (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1.ft CW
2.ta 8n +8n +8n +8n +8n +8n +8n
3.ft
4.TL
5A Manual for the Plan 9 assembler
6.AU
7Rob Pike
8rob@plan9.att.com
9.SH
10Machines
11.PP
12There is an assembler for each of the MIPS, SPARC, Intel 386,
13Intel 960, AT&T DSP3210, and Motorola 68020.
14The 68020 assembler,
15.CW 2a ,
16is the oldest and in many ways the prototype.
17The assemblers are really just variations of a single program:
18they share many properties such as left-to-right assignment order for
19instruction operands and the synthesis of macro instructions
20such as
21.CW MOVE
22to hide the peculiarities of the load and store structure of the machines.
23To keep things concrete, the first part of this manual is
24specifically about the 68020.
25At the end is a description of the differences among
26the other assemblers.
27.PP
28The document, ``How to Use the Plan 9 C Compiler'', by Rob Pike,
29is a prerequisite for this manual.
30.SH
31Registers
32.PP
33All pre-defined symbols in the assembler are upper-case.
34Data registers are
35.CW R0
36through
37.CW R7 ;
38address registers are
39.CW A0
40through
41.CW A7 ;
42floating-point registers are
43.CW F0
44through
45.CW F7 .
46.PP
47A pointer in
48.CW A6
49is used by the C compiler to point to data, enabling short addresses to
50be used more often.
51The value of
52.CW A6
53is constant and must be set during C program initialization
54to the address of the externally-defined symbol
55.CW a6base .
56.PP
57The following hardware registers are defined in the assembler; their
58meaning should be obvious given a 68020 manual:
59.CW CAAR ,
60.CW CACR ,
61.CW CCR ,
62.CW DFC ,
63.CW ISP ,
64.CW MSP ,
65.CW SFC ,
66.CW SR ,
67.CW USP ,
68and
69.CW VBR .
70.PP
71The assembler also defines several pseudo-registers that
72manipulate the stack:
73.CW FP ,
74.CW SP ,
75and
76.CW TOS .
77.CW FP
78is the frame pointer, so
79.CW 0(FP)
80is the first argument,
81.CW 4(FP)
82is the second, and so on.
83.CW SP
84is the local stack pointer, where automatic variables are held
85(SP is a pseudo-register only on the 68020);
86.CW 0(SP)
87is the first automatic, and so on as with
88.CW FP .
89Finally,
90.CW TOS
91is the top-of-stack register, used for pushing parameters to procedures,
92saving temporary values, and so on.
93.PP
94The assembler and loader track these pseudo-registers so
95the above statements are true regardless of what has been
96pushed on the hardware stack, pointed to by
97.CW A7 .
98The name
99.CW A7
100refers to the hardware stack pointer, but beware of mixed use of
101.CW A7
102and the above stack-related pseudo-registers, which will cause trouble.
103Note, too, that the
104.CW PEA
105instruction is observed by the loader to
106alter SP and thus will insert a corresponding pop before all returns.
107The assembler accepts a label-like name to be attached to
108.CW FP
109and
110.CW SP
111uses, such as
112.CW p+0(FP) ,
113to help document that
114.CW p
115is the first argument to a routine.
116The name goes in the symbol table but has no significance to the result
117of the program.
118.SH
119Referring to data
120.PP
121All external references must be made relative to some pseudo-register,
122either
123.CW PC
124(the virtual program counter) or
125.CW SB
126(the ``static base'' register).
127.CW PC
128counts instructions, not bytes of data.
129For example, to branch to the second following instruction, that is,
130to skip one instruction, one may write
131.P1
132	BRA	2(PC)
133.P2
134Labels are also allowed, as in
135.P1
136	BRA	return
137	NOP
138return:
139	RTS
140.P2
141When using labels, there is no
142.CW (PC)
143annotation.
144.PP
145The pseudo-register
146.CW SB
147refers to the beginning of the address space of the program.
148Thus, references to global data and procedures are written as
149offsets to
150.CW SB ,
151as in
152.P1
153	MOVL	$array(SB), TOS
154.P2
155to push the address of a global array on the stack, or
156.P1
157	MOVL	array+4(SB), TOS
158.P2
159to push the second (4-byte) element of the array.
160Note the use of an offset; the complete list of addressing modes is given below.
161Similarly, subroutine calls must use
162.CW SB :
163.P1
164	BSR	exit(SB)
165.P2
166File-static variables have syntax
167.P1
168	local<>+4(SB)
169.P2
170The
171.CW <>
172will be filled in at load time by a unique integer.
173.PP
174When a program starts, it must execute
175.P1
176	MOVL	$a6base(SB), A6
177.P2
178before accessing any global data.
179(On machines such as the MIPS and SPARC that cannot load a register
180in a single instruction, constants are loaded through the static base
181register.  The loader recognizes code that initializes the static
182base register and treats it specially.  You must be careful, however,
183not to load large constants on such machines when the static base
184register is not set up, such as early in interrupt routines.)
185.SH
186Expressions
187.PP
188Expressions are mostly what one might expect.
189Where an offset or a constant is expected,
190a primary expression with unary operators is allowed.
191A general C constant expression is allowed in parentheses.
192.PP
193Source files are preprocessed exactly as in the C compiler, so
194.CW #define
195and
196.CW #include
197work.
198.SH
199Addressing modes
200.PP
201The simple addressing modes are shared by all the assemblers.
202Here, for completeness, follows a table of all the 68020 addressing modes,
203since that machine has the richest set.
204In the table,
205.CW o
206is an offset, which if zero may be elided.
207Many of the modes listed have the same name;
208scrutiny of the format will show what default is being applied.
209For instance, indexed mode with no address register supplied operates
210as though a zero-valued register were used.
211For "offset" read "displacement."
212For "\f(CW.s\fP" read one of
213.CW .L ,
214or
215.CW .W
216followed by
217.CW *1 ,
218.CW *2 ,
219.CW *4 ,
220or
221.CW *8
222to indicate the size and scaling of the data.
223.IP
224.TS
225l lfCW.
226data register	R0
227address register	A0
228floating-point register	F0
229special names	CAAR, CACR, etc.
230constant	$con
231floating point constant	$fcon
232external symbol	name+o(SB)
233local symbol	name<>+o(SB)
234automatic symbol	name+o(SP)
235argument	name+o(FP)
236address of external	$name+o(SB)
237address of local	$name<>+o(SB)
238indirect post-increment	(A0)+
239indirect pre-decrement	-(A0)
240indirect with offset	o(A0)
241indexed with offset	o()(R0.s)
242indexed with offset	o(A0)(R0.s)
243external indexed	name+o(SB)(R0.s)
244local indexed	name<>+o(SB)(R0.s)
245automatic indexed	name+o(SP)(R0.s)
246parameter indexed	name+o(FP)(R0.s)
247offset indirect post-indexed	d(o())(R0.s)
248offset indirect post-indexed	d(o(A0))(R0.s)
249external indirect post-indexed	d(name+o(SB))(R0.s)
250local indirect post-indexed	d(name<>+o(SB))(R0.s)
251automatic indirect post-indexed	d(name+o(SP))(R0.s)
252parameter indirect post-indexed	d(name+o(FP))(R0.s)
253offset indirect pre-indexed	d(o()(R0.s))
254offset indirect pre-indexed	d(o(A0))
255offset indirect pre-indexed	d(o(A0)(R0.s))
256external indirect pre-indexed	d(name+o(SB))
257external indirect pre-indexed	d(name+o(SB)(R0.s))
258local indirect pre-indexed	d(name<>+o(SB))
259local indirect pre-indexed	d(name<>+o(SB)(R0.s))
260automatic indirect pre-indexed	d(name+o(SP))
261automatic indirect pre-indexed	d(name+o(SP)(R0.s))
262parameter indirect pre-indexed	d(name+o(FP))
263parameter indirect pre-indexed	d(name+o(FP)(R0.s))
264.TE
265.in
266.SH
267Laying down data
268.PP
269Placing data in the instruction stream, say for interrupt vectors, is easy:
270the pseudo-instructions
271.CW LONG
272and
273.CW WORD
274(but not
275.CW BYTE )
276lay down the value of their single argument, of the appropriate size,
277as if it were an instruction:
278.P1
279	LONG	$12345
280.P2
281places the long 12345 (base 10)
282in the instruction stream.
283(On all machines except the 68020, the only such operator is
284.CW WORD
285and it lays down 32-bit quantities.)
286.PP
287Placing information in the data section is more painful.
288The pseudo-instruction
289.CW DATA
290does the work, given two arguments: an address at which to place the item,
291including its size,
292and the value to place there.  For example, to define a character array
293.CW array
294containing the characters
295.CW abc
296and a terminating null:
297.P1
298	DATA    array+0(SB)/1, $'a'
299	DATA    array+1(SB)/1, $'b'
300	DATA    array+2(SB)/1, $'c'
301	GLOBL   array(SB), $4
302.P2
303or
304.P1
305	DATA    array+0(SB)/4, $"abc\ez"
306	GLOBL   array(SB), $4
307.P2
308The
309.CW /1
310defines the number of bytes to define,
311.CW GLOBL
312makes the symbol global, and the
313.CW $4
314says how many bytes the symbol occupies.
315Uninitialized data is zeroed automatically.
316The character
317.CW \ez
318is equivalent to the C
319.CW \e0.
320The string in a
321.CW DATA
322statement may contain a maximum of eight bytes;
323build larger strings piecewise.
324Two pseudo-instructions,
325.CW DYNT
326and
327.CW INIT ,
328allow the Alef compilers to build dynamic type information during the load
329phase.
330The
331.CW DYNT
332pseudo-instruction has two forms:
333.P1
334	DYNT	, ALEF_SI_5+0(SB)
335	DYNT	ALEF_AS+0(SB), ALEF_SI_5+0(SB)
336.P2
337In the first form,
338.CW DYNT
339defines the symbol to be a small unique integer constant, chosen by the loader,
340which is some multiple of the word size.  In the second form,
341.CW DYNT
342defines the second symbol in the same way,
343places the address of the most recently
344defined text symbol in the array specified by the first symbol at the
345index defined by the value of the second symbol,
346and then adjusts the size of the array accordingly.
347.PP
348The
349.CW INIT
350pseudo-instruction takes the same parameters as a
351.CW DATA
352statement.  Its symbol is used as the base of an array and the
353data item is installed in the array at the offset specified by the most recent
354.CW DYNT
355pseudo-instruction.
356The size of the array is adjusted accordingly.
357The
358.CW DYNT
359and
360.CW INIT
361pseudo-instructions are not implemented on the 68020.
362.SH
363Defining a procedure
364.PP
365Entry points are defined by the pseudo-operation
366.CW TEXT ,
367which takes as arguments the name of the procedure (including the ubiquitous
368.CW (SB) )
369and the number of bytes of automatic storage to pre-allocate on the stack,
370which will usually be zero when writing assembly language programs.
371On the MIPS and SPARC, the special value -4 instructs the loader to generate no PC save
372and restore instructions, even if the function is not a leaf.
373Here is a complete procedure that returns the sum
374of its two arguments:
375.P1
376TEXT	sum(SB), $0
377	MOVL	arg1+0(FP), R0
378	ADDL	arg2+4(FP), R0
379	RTS
380.P2
381An optional middle argument
382to the
383.CW TEXT
384pseudo-op is a bit field of options to the loader.
385Setting the 1 bit suspends profiling the function when profiling is enabled for the rest of
386the program.
387For example,
388.P1
389TEXT	sum(SB), 1, $0
390	MOVL	arg1+0(FP), R0
391	ADDL	arg2+4(FP), R0
392	RTS
393.P2
394will not be profiled; the first version above would be.
395Subroutines with peculiar state, such as system call routines,
396should not be profiled.
397.PP
398Setting the 2 bit allows multiple definitions of the same
399.CW TEXT
400symbol in a program; the loader will place only one such function in the image.
401It is emitted only by the Alef compilers.
402.PP
403Subroutines to be called from C should place their result in
404.CW R0 ,
405even if it is an address.
406Floating point values are returned in
407.CW F0 .
408Functions that return a structure to a C program
409receive as their first argument the address of the location to
410store the result;
411.CW R0
412is unused in the calling protocol for such procedures.
413A subroutine is responsible for saving its own registers,
414and therefore is free to use any registers without saving them (``caller saves'').
415.CW A6
416and
417.CW A7
418are the exceptions as described above.
419.SH
420When in doubt
421.PP
422If you get confused, try using the
423.CW -S
424option to
425.CW 2c
426and compiling a sample program.
427The standard output is valid input to the assembler.
428.SH
429Instructions
430.PP
431The instruction set of the assembler is not identical to that
432of the machine.
433It is chosen to match what the compiler generates, augmented
434slightly by specific needs of the operating system.
435For example,
436.CW 2a
437does not distinguish between the various forms of
438.CW MOVE
439instruction: move quick, move address, etc.  Instead the context
440does the job.  For example,
441.P1
442	MOVL	$1, R1
443	MOVL	A0, R2
444	MOVW	SR, R3
445.P2
446generates official
447.CW MOVEQ ,
448.CW MOVEA ,
449and
450.CW MOVESR
451instructions.
452A number of instructions do not have the syntax necessary to specify
453their entire capabilities.  Notable examples are the bitfield
454instructions, the
455multiply and divide instructions, etc.
456For a complete set of generated instruction names (in
457.CW 2a
458notation, not Motorola's) see the file
459.CW /sys/src/cmd/2c/2.out.h .
460Despite its name, this file contains an enumeration of the
461instructions that appear in the intermediate files generated
462by the compiler, which correspond exactly to lines of assembly language.
463.SH
464Laying down instructions
465.PP
466The loader modifies the code produced by the assembler and compiler.
467It folds branches,
468copies short sequences of code to eliminate branches,
469and discards unreachable code.
470The first instruction of every function is assumed to be reachable.
471The pseudo-instruction
472.CW NOP ,
473which you may see in compiler output,
474means no instruction at all, rather than an instruction that does nothing.
475The loader discards all
476.CW NOP 's.
477.PP
478To generate a true
479.CW NOP
480instruction, or any other instruction not known to the assembler, use a
481.CW WORD
482pseudo-instruction.
483Such instructions on RISCs are not scheduled by the loader and must have
484their delay slots filled manually.
485.SH
486MIPS
487.PP
488The registers are only addressed by number:
489.CW R0
490through
491.CW R31 .
492.CW R29
493is the stack pointer;
494.CW R30
495is used as the static base pointer, the analogue of
496.CW A6
497on the 68020.
498Its value is the address of the global symbol
499.CW setR30(SB) .
500The register holding returned values from subroutines is
501.CW R1 .
502When a function is called, space for the first argument
503is reserved at
504.CW 0(FP)
505but in C (not Alef) the value is passed in
506.CW R1
507instead.
508.PP
509The loader uses
510.CW R28
511as a temporary.  The system uses
512.CW R26
513and
514.CW R27
515as interrupt-time temporaries.  Therefore none of these registers
516should be used in user code.
517.PP
518The control registers are not known to the assembler.
519Instead they are numbered registers
520.CW M0 ,
521.CW M1 ,
522etc.
523Use this trick to access, say,
524.CW STATUS :
525.P1
526#define	STATUS	12
527	MOVW	M(STATUS), R1
528.P2
529.PP
530Floating point registers are called
531.CW F0
532through
533.CW F31 .
534By convention,
535.CW F24
536must be initialized to the value 0.0,
537.CW F26
538to 0.5,
539.CW F28
540to 1.0, and
541.CW F30
542to 2.0;
543this is done by the operating system.
544.PP
545The instructions and their syntax are different from those of the manufacturer's
546manual.
547There are no
548.CW lui
549and kin; instead there are
550.CW MOVW
551(move word),
552.CW MOVH
553(move halfword),
554and
555.CW MOVB
556(move byte) pseudo-instructions.  If the operand is unsigned, the instructions
557are
558.CW MOVHU
559and
560.CW MOVBU .
561The order of operands is from left to right in dataflow order, just as
562on the 68020 but not as in MIPS documentation.
563This means that the
564.CW Bcond
565instructions are reversed with respect to the book; for example, a
566.CW va
567.CW BGTZ
568generates a MIPS
569.CW bltz
570instruction.
571.PP
572The assembler is for the R2000, R3000, and most of the R4000 and R6000 architectures.
573It understands the 64-bit instructions
574.CW MOVV ,
575.CW MOVVL ,
576.CW ADDV ,
577.CW ADDVU ,
578.CW SUBV ,
579.CW SUBVU ,
580.CW MULV ,
581.CW MULVU ,
582.CW DIVV ,
583.CW DIVVU ,
584.CW SLLV ,
585.CW SRLV ,
586and
587.CW SRAV .
588The assembler does not have any cache, load-linked, or store-conditional instructions.
589.PP
590Some assembler instructions are expanded into multiple instructions by the loader.
591For example the loader may convert the load of a 32 bit constant into an
592.CW lui
593followed by an
594.CW ori .
595.PP
596Assembler instructions should be laid out as if there
597were no load, branch, or floating point compare delay slots;
598the loader will rearrange\(em\f2schedule\f1\(emthe instructions
599to guarantee correctness and improve performance.
600The only exception is that the correct scheduling of instructions
601that use control registers varies from model to model of machine
602(and is often undocumented) so you should schedule such instructions
603by hand to guarantee correct behavior.
604The loader generates
605.P1
606	NOR	R0, R0, R0
607.P2
608when it needs a true no-op instruction.
609Use exactly this instruction when scheduling code manually;
610the loader recognizes it and schedules the code before it and after it independently.  Also,
611.CW WORD
612pseudo-ops are scheduled like no-ops.
613.PP
614The
615.CW NOSCHED
616pseudo-op disables instruction scheduling
617(scheduling is enabled by default);
618.CW SCHED
619re-enables it.
620Branch folding, code copying, and dead code elimination are
621disabled for instructions that are not scheduled.
622.SH
623SPARC
624.PP
625Once you understand the Plan 9 model for the MIPS, the SPARC is familiar.
626Registers have numerical names only:
627.CW R0
628through
629.CW R31 .
630Forget about register windows: Plan 9 doesn't use them at all.
631The machine has 32 global registers, period.
632.CW R1
633[sic] is the stack pointer.
634.CW R2
635is the static base register, with value the address of
636.CW setSB(SB) .
637.CW R7
638is the return register and also the register holding the first
639argument to a C (not Alef) function, again with space reserved at
640.CW 0(FP) .
641.CW R14
642is the loader temporary.
643.PP
644Floating-point registers are exactly as on the MIPS.
645.PP
646The control registers are known by names such as
647.CW FSR .
648The instructions to access these registers are
649.CW MOVW
650instructions, for example
651.P1
652	MOVW	Y, R8
653.P2
654for the SPARC instruction
655.P1
656	rdy	%r8
657.P2
658.PP
659Move instructions are similar to those on the MIPS: pseudo-operations
660that turn into appropriate sequences of
661.CW sethi
662instructions, adds, etc.
663Instructions read from left to right.  Because the arguments are
664flipped to
665.CW SUBCC ,
666the condition codes are not inverted as on the MIPS.
667.PP
668The syntax for the ASI stuff is, for example to move a word from ASI 2:
669.P1
670	MOVW	(R7, 2), R8
671.P2
672The syntax for double indexing is
673.P1
674	MOVW	(R7+R8), R9
675.P2
676.PP
677The SPARC's instruction scheduling is similar to the MIPS's.
678The official no-op instruction is:
679.P1
680	ORN	R0, R0, R0
681.P2
682.SH
683i960
684.PP
685Registers are numbered
686.CW R0
687through
688.CW R31 .
689Stack pointer is
690.CW R29 ;
691return register is
692.CW R4 ;
693static base is
694.CW R28 ;
695it is initialized to the address of
696.CW setSB(SB) .
697.CW R3
698must be zero; this should be done manually early in execution by
699.P1
700	SUBO	R3, R3
701.P2
702.CW R27
703is the loader temporary.
704.PP
705There is no support for floating point.
706.PP
707The Intel calling convention is not supported and cannot be used; use
708.CW BAL
709instead.
710Instructions are mostly as in the book.  The major change is that
711.CW LOAD
712and
713.CW STORE
714are both called
715.CW MOV .
716The extension character for
717.CW MOV
718is as in the manual:
719.CW O
720for ordinal,
721.CW W
722for signed, etc.
723.SH
724i386
725.PP
726The assembler assumes 32-bit protected mode.
727The register names are
728.CW SP ,
729.CW AX ,
730.CW BX ,
731.CW CX ,
732.CW DX ,
733.CW BP ,
734.CW DI ,
735and
736.CW SI .
737The stack pointer (not a pseudo-register) is
738.CW SP
739and the return register is
740.CW AX .
741There is no physical frame pointer but, as for the MIPS,
742.CW FP
743is a pseudo-register that acts as
744a frame pointer.
745.PP
746Opcode names are mostly the same as those listed in the Intel manual
747with an
748.CW L ,
749.CW W ,
750or
751.CW B
752appended to identify 32-bit,
75316-bit, and 8-bit operations.
754The exceptions are loads, stores, and conditionals.
755All load and store opcodes to and from general registers, special registers
756(such as
757.CW CR0,
758.CW CR3,
759.CW GDTR,
760.CW IDTR,
761.CW SS,
762.CW CS,
763.CW DS,
764.CW ES,
765.CW FS,
766and
767.CW GS )
768or memory are written
769as
770.P1
771	MOV\f2x\fP	src,dst
772.P2
773where
774.I x
775is
776.CW L ,
777.CW W ,
778or
779.CW B .
780Thus to get
781.CW AL
782use a
783.CW MOVB
784instruction.  If you need to access
785.CW AH ,
786you must mention it explicitly in a
787.CW MOVB :
788.P1
789	MOVB	AH, BX
790.P2
791There are many examples of illegal moves, for example,
792.P1
793	MOVB	BP, DI
794.P2
795that the loader actually implements as pseudo-operations.
796.PP
797The names of conditions in all conditional instructions
798.CW J , (
799.CW SET )
800follow the conventions of the 68020 instead of those of the Intel
801assembler:
802.CW JOS ,
803.CW JOC ,
804.CW JCS ,
805.CW JCC ,
806.CW JEQ ,
807.CW JNE ,
808.CW JLS ,
809.CW JHI ,
810.CW JMI ,
811.CW JPL ,
812.CW JPS ,
813.CW JPC ,
814.CW JLT ,
815.CW JGE ,
816.CW JLE ,
817and
818.CW JGT
819instead of
820.CW JO ,
821.CW JNO ,
822.CW JB ,
823.CW JNB ,
824.CW JZ ,
825.CW JNZ ,
826.CW JBE ,
827.CW JNBE ,
828.CW JS ,
829.CW JNS ,
830.CW JP ,
831.CW JNP ,
832.CW JL ,
833.CW JNL ,
834.CW JLE ,
835and
836.CW JNLE .
837.PP
838The addressing modes have syntax like
839.CW AX ,
840.CW (AX) ,
841.CW (AX)(BX*4) ,
842.CW 10(AX) ,
843and
844.CW 10(AX)(BX*4) .
845The offsets from
846.CW AX
847can be replaced by offsets from
848.CW FP
849or
850.CW SB
851to access names, for example
852.CW extern+5(SB)(AX*2) .
853.PP
854Other notes: Non-relative
855.CW JMP
856and
857.CW CALL
858have a
859.CW *
860added to the syntax.
861Only
862.CW LOOP ,
863.CW LOOPEQ ,
864and
865.CW LOOPNE
866are legal loop instructions.  Only
867.CW REP
868and
869.CW REPN
870are recognized repeaters.  These are not prefixes, but rather
871stand-alone opcodes that precede the strings, for example
872.P1
873	CLD; REP; MOVSL
874.P2
875Segment override prefixes in
876.CW MOD/RM
877fields are not supported.
878.SH
8793210
880.PP
881Opcode names for integer instructions follow the conventions used for the MIPS,
882with an appended
883.CW H
884indicating a 16-bit operation.
885The unusual instructions are
886.CW ADDCR ,
887.CW ADDN ,
888.CW BIT ,
889.CW CALL ,
890.CW DBRA ,
891.CW IRET ,
892.CW ROL ,
893.CW ROR ,
894.CW SUBR ,
895.CW SFTRST ,
896and
897.CW WAITI .
898The condition to test is specified as the first parameter to conditional opcodes.
899.PP
900The basic floating arithmetic opcodes are
901.CW FMUL ,
902.CW FADD ,
903.CW FSUB ,
904.CW FMADD ,
905and
906.CW FMSUB .
907A
908.CW T
909suffix specifies the tap versions of the instructions,
910while a
911.CW N
912suffix negates the accumulator argument.
913The parameters are in the reverse order from the 3210 manual.
914An
915.CW FDIV
916pseudo-op is provided.
917Conversions are specified as moves; the remaining floating instructions are
918.CW FIEEE ,
919.CW FDSP ,
920.CW FROUND ,
921.CW FSEED ,
922.CW FIFEQ ,
923.CW FIFEQ ,
924.CW FIFGT ,
925and
926.CW FIFLT .
927.PP
928.CW DO
929instructions take as a second parameter the number of instructions in the loop
930or a label that points to a
931.CW DOEND
932instruction.
933.CW DOEND
934instructions have one parameter, a label pointing to the corresponding
935.CW DO
936instruction.
937All instructions between the
938.CW DO
939and
940.CW DOEND
941instructions are in the loop.
942.CW DOLOCK
943instructions have the same syntax as
944.CW DO
945instructions.
946.CW BMOVW
947is a block move instruction macro.
948.PP
949Instructions are scheduled like MIPS instructions.
950Floating point instructions are scheduled.
951.PP
952The condition codes are capitalized versions of the standard 3210 names,
953with the exception that an F is prefixed for floating point and an O is used
954for overflows.
955