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