1426d2b71SDavid du Colombier.HTML "A Manual for the Plan 9 assembler 23e12c5d1SDavid du Colombier.ft CW 33e12c5d1SDavid du Colombier.ta 8n +8n +8n +8n +8n +8n +8n 43e12c5d1SDavid du Colombier.ft 53e12c5d1SDavid du Colombier.TL 6219b2ee8SDavid du ColombierA Manual for the Plan 9 assembler 73e12c5d1SDavid du Colombier.AU 83e12c5d1SDavid du ColombierRob Pike 97dd7cddfSDavid du Colombierrob@plan9.bell-labs.com 103e12c5d1SDavid du Colombier.SH 113e12c5d1SDavid du ColombierMachines 123e12c5d1SDavid du Colombier.PP 13*f54a2a50SDavid du ColombierThere is an assembler for each of the MIPS, SPARC, Intel 386, AMD64, 14*f54a2a50SDavid du ColombierPower PC, and ARM. 153e12c5d1SDavid du ColombierThe 68020 assembler, 163e12c5d1SDavid du Colombier.CW 2a , 17*f54a2a50SDavid du Colombier(no longer distributed) 183e12c5d1SDavid du Colombieris the oldest and in many ways the prototype. 19219b2ee8SDavid du ColombierThe assemblers are really just variations of a single program: 20219b2ee8SDavid du Colombierthey share many properties such as left-to-right assignment order for 21219b2ee8SDavid du Colombierinstruction operands and the synthesis of macro instructions 22219b2ee8SDavid du Colombiersuch as 23219b2ee8SDavid du Colombier.CW MOVE 24219b2ee8SDavid du Colombierto hide the peculiarities of the load and store structure of the machines. 253e12c5d1SDavid du ColombierTo keep things concrete, the first part of this manual is 263e12c5d1SDavid du Colombierspecifically about the 68020. 27219b2ee8SDavid du ColombierAt the end is a description of the differences among 283e12c5d1SDavid du Colombierthe other assemblers. 29219b2ee8SDavid du Colombier.PP 30219b2ee8SDavid du ColombierThe document, ``How to Use the Plan 9 C Compiler'', by Rob Pike, 31219b2ee8SDavid du Colombieris a prerequisite for this manual. 323e12c5d1SDavid du Colombier.SH 333e12c5d1SDavid du ColombierRegisters 343e12c5d1SDavid du Colombier.PP 353e12c5d1SDavid du ColombierAll pre-defined symbols in the assembler are upper-case. 363e12c5d1SDavid du ColombierData registers are 373e12c5d1SDavid du Colombier.CW R0 383e12c5d1SDavid du Colombierthrough 393e12c5d1SDavid du Colombier.CW R7 ; 403e12c5d1SDavid du Colombieraddress registers are 413e12c5d1SDavid du Colombier.CW A0 423e12c5d1SDavid du Colombierthrough 433e12c5d1SDavid du Colombier.CW A7 ; 443e12c5d1SDavid du Colombierfloating-point registers are 453e12c5d1SDavid du Colombier.CW F0 463e12c5d1SDavid du Colombierthrough 473e12c5d1SDavid du Colombier.CW F7 . 483e12c5d1SDavid du Colombier.PP 493e12c5d1SDavid du ColombierA pointer in 503e12c5d1SDavid du Colombier.CW A6 513e12c5d1SDavid du Colombieris used by the C compiler to point to data, enabling short addresses to 523e12c5d1SDavid du Colombierbe used more often. 533e12c5d1SDavid du ColombierThe value of 543e12c5d1SDavid du Colombier.CW A6 553e12c5d1SDavid du Colombieris constant and must be set during C program initialization 563e12c5d1SDavid du Colombierto the address of the externally-defined symbol 573e12c5d1SDavid du Colombier.CW a6base . 583e12c5d1SDavid du Colombier.PP 593e12c5d1SDavid du ColombierThe following hardware registers are defined in the assembler; their 603e12c5d1SDavid du Colombiermeaning should be obvious given a 68020 manual: 613e12c5d1SDavid du Colombier.CW CAAR , 623e12c5d1SDavid du Colombier.CW CACR , 633e12c5d1SDavid du Colombier.CW CCR , 643e12c5d1SDavid du Colombier.CW DFC , 653e12c5d1SDavid du Colombier.CW ISP , 663e12c5d1SDavid du Colombier.CW MSP , 673e12c5d1SDavid du Colombier.CW SFC , 683e12c5d1SDavid du Colombier.CW SR , 69219b2ee8SDavid du Colombier.CW USP , 703e12c5d1SDavid du Colombierand 713e12c5d1SDavid du Colombier.CW VBR . 723e12c5d1SDavid du Colombier.PP 733e12c5d1SDavid du ColombierThe assembler also defines several pseudo-registers that 743e12c5d1SDavid du Colombiermanipulate the stack: 753e12c5d1SDavid du Colombier.CW FP , 763e12c5d1SDavid du Colombier.CW SP , 773e12c5d1SDavid du Colombierand 783e12c5d1SDavid du Colombier.CW TOS . 793e12c5d1SDavid du Colombier.CW FP 803e12c5d1SDavid du Colombieris the frame pointer, so 813e12c5d1SDavid du Colombier.CW 0(FP) 823e12c5d1SDavid du Colombieris the first argument, 833e12c5d1SDavid du Colombier.CW 4(FP) 843e12c5d1SDavid du Colombieris the second, and so on. 853e12c5d1SDavid du Colombier.CW SP 86219b2ee8SDavid du Colombieris the local stack pointer, where automatic variables are held 87219b2ee8SDavid du Colombier(SP is a pseudo-register only on the 68020); 883e12c5d1SDavid du Colombier.CW 0(SP) 893e12c5d1SDavid du Colombieris the first automatic, and so on as with 903e12c5d1SDavid du Colombier.CW FP . 913e12c5d1SDavid du ColombierFinally, 923e12c5d1SDavid du Colombier.CW TOS 933e12c5d1SDavid du Colombieris the top-of-stack register, used for pushing parameters to procedures, 943e12c5d1SDavid du Colombiersaving temporary values, and so on. 953e12c5d1SDavid du Colombier.PP 963e12c5d1SDavid du ColombierThe assembler and loader track these pseudo-registers so 973e12c5d1SDavid du Colombierthe above statements are true regardless of what has been 983e12c5d1SDavid du Colombierpushed on the hardware stack, pointed to by 993e12c5d1SDavid du Colombier.CW A7 . 1003e12c5d1SDavid du ColombierThe name 1013e12c5d1SDavid du Colombier.CW A7 1023e12c5d1SDavid du Colombierrefers to the hardware stack pointer, but beware of mixed use of 1033e12c5d1SDavid du Colombier.CW A7 1043e12c5d1SDavid du Colombierand the above stack-related pseudo-registers, which will cause trouble. 1053e12c5d1SDavid du ColombierNote, too, that the 1063e12c5d1SDavid du Colombier.CW PEA 1073e12c5d1SDavid du Colombierinstruction is observed by the loader to 1083e12c5d1SDavid du Colombieralter SP and thus will insert a corresponding pop before all returns. 1093e12c5d1SDavid du ColombierThe assembler accepts a label-like name to be attached to 1103e12c5d1SDavid du Colombier.CW FP 1113e12c5d1SDavid du Colombierand 1123e12c5d1SDavid du Colombier.CW SP 1133e12c5d1SDavid du Colombieruses, such as 114219b2ee8SDavid du Colombier.CW p+0(FP) , 1153e12c5d1SDavid du Colombierto help document that 1163e12c5d1SDavid du Colombier.CW p 1173e12c5d1SDavid du Colombieris the first argument to a routine. 1183e12c5d1SDavid du ColombierThe name goes in the symbol table but has no significance to the result 1193e12c5d1SDavid du Colombierof the program. 1203e12c5d1SDavid du Colombier.SH 1213e12c5d1SDavid du ColombierReferring to data 1223e12c5d1SDavid du Colombier.PP 1233e12c5d1SDavid du ColombierAll external references must be made relative to some pseudo-register, 1243e12c5d1SDavid du Colombiereither 1253e12c5d1SDavid du Colombier.CW PC 1263e12c5d1SDavid du Colombier(the virtual program counter) or 1273e12c5d1SDavid du Colombier.CW SB 1283e12c5d1SDavid du Colombier(the ``static base'' register). 1293e12c5d1SDavid du Colombier.CW PC 1303e12c5d1SDavid du Colombiercounts instructions, not bytes of data. 1313e12c5d1SDavid du ColombierFor example, to branch to the second following instruction, that is, 1323e12c5d1SDavid du Colombierto skip one instruction, one may write 1333e12c5d1SDavid du Colombier.P1 1343e12c5d1SDavid du Colombier BRA 2(PC) 1353e12c5d1SDavid du Colombier.P2 1363e12c5d1SDavid du ColombierLabels are also allowed, as in 1373e12c5d1SDavid du Colombier.P1 1383e12c5d1SDavid du Colombier BRA return 1393e12c5d1SDavid du Colombier NOP 1403e12c5d1SDavid du Colombierreturn: 1413e12c5d1SDavid du Colombier RTS 1423e12c5d1SDavid du Colombier.P2 1433e12c5d1SDavid du ColombierWhen using labels, there is no 1443e12c5d1SDavid du Colombier.CW (PC) 1453e12c5d1SDavid du Colombierannotation. 1463e12c5d1SDavid du Colombier.PP 1473e12c5d1SDavid du ColombierThe pseudo-register 1483e12c5d1SDavid du Colombier.CW SB 1493e12c5d1SDavid du Colombierrefers to the beginning of the address space of the program. 1503e12c5d1SDavid du ColombierThus, references to global data and procedures are written as 1513e12c5d1SDavid du Colombieroffsets to 1523e12c5d1SDavid du Colombier.CW SB , 1533e12c5d1SDavid du Colombieras in 1543e12c5d1SDavid du Colombier.P1 1553e12c5d1SDavid du Colombier MOVL $array(SB), TOS 1563e12c5d1SDavid du Colombier.P2 1573e12c5d1SDavid du Colombierto push the address of a global array on the stack, or 1583e12c5d1SDavid du Colombier.P1 1593e12c5d1SDavid du Colombier MOVL array+4(SB), TOS 1603e12c5d1SDavid du Colombier.P2 1613e12c5d1SDavid du Colombierto push the second (4-byte) element of the array. 1623e12c5d1SDavid du ColombierNote the use of an offset; the complete list of addressing modes is given below. 1633e12c5d1SDavid du ColombierSimilarly, subroutine calls must use 1643e12c5d1SDavid du Colombier.CW SB : 1653e12c5d1SDavid du Colombier.P1 1663e12c5d1SDavid du Colombier BSR exit(SB) 1673e12c5d1SDavid du Colombier.P2 1683e12c5d1SDavid du ColombierFile-static variables have syntax 1693e12c5d1SDavid du Colombier.P1 1703e12c5d1SDavid du Colombier local<>+4(SB) 1713e12c5d1SDavid du Colombier.P2 1723e12c5d1SDavid du ColombierThe 1733e12c5d1SDavid du Colombier.CW <> 1743e12c5d1SDavid du Colombierwill be filled in at load time by a unique integer. 1753e12c5d1SDavid du Colombier.PP 1763e12c5d1SDavid du ColombierWhen a program starts, it must execute 1773e12c5d1SDavid du Colombier.P1 1783e12c5d1SDavid du Colombier MOVL $a6base(SB), A6 1793e12c5d1SDavid du Colombier.P2 1803e12c5d1SDavid du Colombierbefore accessing any global data. 1813e12c5d1SDavid du Colombier(On machines such as the MIPS and SPARC that cannot load a register 1823e12c5d1SDavid du Colombierin a single instruction, constants are loaded through the static base 1833e12c5d1SDavid du Colombierregister. The loader recognizes code that initializes the static 1843e12c5d1SDavid du Colombierbase register and treats it specially. You must be careful, however, 1853e12c5d1SDavid du Colombiernot to load large constants on such machines when the static base 1863e12c5d1SDavid du Colombierregister is not set up, such as early in interrupt routines.) 1873e12c5d1SDavid du Colombier.SH 1883e12c5d1SDavid du ColombierExpressions 1893e12c5d1SDavid du Colombier.PP 1903e12c5d1SDavid du ColombierExpressions are mostly what one might expect. 1913e12c5d1SDavid du ColombierWhere an offset or a constant is expected, 1923e12c5d1SDavid du Colombiera primary expression with unary operators is allowed. 1933e12c5d1SDavid du ColombierA general C constant expression is allowed in parentheses. 1943e12c5d1SDavid du Colombier.PP 1953e12c5d1SDavid du ColombierSource files are preprocessed exactly as in the C compiler, so 1963e12c5d1SDavid du Colombier.CW #define 1973e12c5d1SDavid du Colombierand 1983e12c5d1SDavid du Colombier.CW #include 1993e12c5d1SDavid du Colombierwork. 2003e12c5d1SDavid du Colombier.SH 201219b2ee8SDavid du ColombierAddressing modes 202219b2ee8SDavid du Colombier.PP 203219b2ee8SDavid du ColombierThe simple addressing modes are shared by all the assemblers. 204219b2ee8SDavid du ColombierHere, for completeness, follows a table of all the 68020 addressing modes, 205219b2ee8SDavid du Colombiersince that machine has the richest set. 206219b2ee8SDavid du ColombierIn the table, 207219b2ee8SDavid du Colombier.CW o 2087dd7cddfSDavid du Colombieris an offset, which if zero may be elided, and 2097dd7cddfSDavid du Colombier.CW d 2107dd7cddfSDavid du Colombieris a displacement, which is a constant between -128 and 127 inclusive. 211219b2ee8SDavid du ColombierMany of the modes listed have the same name; 212219b2ee8SDavid du Colombierscrutiny of the format will show what default is being applied. 213219b2ee8SDavid du ColombierFor instance, indexed mode with no address register supplied operates 214219b2ee8SDavid du Colombieras though a zero-valued register were used. 215219b2ee8SDavid du ColombierFor "offset" read "displacement." 216219b2ee8SDavid du ColombierFor "\f(CW.s\fP" read one of 217219b2ee8SDavid du Colombier.CW .L , 218219b2ee8SDavid du Colombieror 219219b2ee8SDavid du Colombier.CW .W 220219b2ee8SDavid du Colombierfollowed by 221219b2ee8SDavid du Colombier.CW *1 , 222219b2ee8SDavid du Colombier.CW *2 , 223219b2ee8SDavid du Colombier.CW *4 , 224219b2ee8SDavid du Colombieror 225219b2ee8SDavid du Colombier.CW *8 226219b2ee8SDavid du Colombierto indicate the size and scaling of the data. 227219b2ee8SDavid du Colombier.IP 228219b2ee8SDavid du Colombier.TS 229219b2ee8SDavid du Colombierl lfCW. 230219b2ee8SDavid du Colombierdata register R0 231219b2ee8SDavid du Colombieraddress register A0 232219b2ee8SDavid du Colombierfloating-point register F0 233219b2ee8SDavid du Colombierspecial names CAAR, CACR, etc. 234219b2ee8SDavid du Colombierconstant $con 235219b2ee8SDavid du Colombierfloating point constant $fcon 236219b2ee8SDavid du Colombierexternal symbol name+o(SB) 237219b2ee8SDavid du Colombierlocal symbol name<>+o(SB) 238219b2ee8SDavid du Colombierautomatic symbol name+o(SP) 239219b2ee8SDavid du Colombierargument name+o(FP) 240219b2ee8SDavid du Colombieraddress of external $name+o(SB) 241219b2ee8SDavid du Colombieraddress of local $name<>+o(SB) 242219b2ee8SDavid du Colombierindirect post-increment (A0)+ 243219b2ee8SDavid du Colombierindirect pre-decrement -(A0) 244219b2ee8SDavid du Colombierindirect with offset o(A0) 245219b2ee8SDavid du Colombierindexed with offset o()(R0.s) 246219b2ee8SDavid du Colombierindexed with offset o(A0)(R0.s) 247219b2ee8SDavid du Colombierexternal indexed name+o(SB)(R0.s) 248219b2ee8SDavid du Colombierlocal indexed name<>+o(SB)(R0.s) 249219b2ee8SDavid du Colombierautomatic indexed name+o(SP)(R0.s) 250219b2ee8SDavid du Colombierparameter indexed name+o(FP)(R0.s) 251219b2ee8SDavid du Colombieroffset indirect post-indexed d(o())(R0.s) 252219b2ee8SDavid du Colombieroffset indirect post-indexed d(o(A0))(R0.s) 253219b2ee8SDavid du Colombierexternal indirect post-indexed d(name+o(SB))(R0.s) 254219b2ee8SDavid du Colombierlocal indirect post-indexed d(name<>+o(SB))(R0.s) 255219b2ee8SDavid du Colombierautomatic indirect post-indexed d(name+o(SP))(R0.s) 256219b2ee8SDavid du Colombierparameter indirect post-indexed d(name+o(FP))(R0.s) 257219b2ee8SDavid du Colombieroffset indirect pre-indexed d(o()(R0.s)) 258219b2ee8SDavid du Colombieroffset indirect pre-indexed d(o(A0)) 259219b2ee8SDavid du Colombieroffset indirect pre-indexed d(o(A0)(R0.s)) 260219b2ee8SDavid du Colombierexternal indirect pre-indexed d(name+o(SB)) 261219b2ee8SDavid du Colombierexternal indirect pre-indexed d(name+o(SB)(R0.s)) 262219b2ee8SDavid du Colombierlocal indirect pre-indexed d(name<>+o(SB)) 263219b2ee8SDavid du Colombierlocal indirect pre-indexed d(name<>+o(SB)(R0.s)) 264219b2ee8SDavid du Colombierautomatic indirect pre-indexed d(name+o(SP)) 265219b2ee8SDavid du Colombierautomatic indirect pre-indexed d(name+o(SP)(R0.s)) 266219b2ee8SDavid du Colombierparameter indirect pre-indexed d(name+o(FP)) 267219b2ee8SDavid du Colombierparameter indirect pre-indexed d(name+o(FP)(R0.s)) 268219b2ee8SDavid du Colombier.TE 269219b2ee8SDavid du Colombier.in 270219b2ee8SDavid du Colombier.SH 2713e12c5d1SDavid du ColombierLaying down data 2723e12c5d1SDavid du Colombier.PP 2733e12c5d1SDavid du ColombierPlacing data in the instruction stream, say for interrupt vectors, is easy: 2743e12c5d1SDavid du Colombierthe pseudo-instructions 2753e12c5d1SDavid du Colombier.CW LONG 2763e12c5d1SDavid du Colombierand 2773e12c5d1SDavid du Colombier.CW WORD 2783e12c5d1SDavid du Colombier(but not 2793e12c5d1SDavid du Colombier.CW BYTE ) 2803e12c5d1SDavid du Colombierlay down the value of their single argument, of the appropriate size, 2813e12c5d1SDavid du Colombieras if it were an instruction: 2823e12c5d1SDavid du Colombier.P1 2833e12c5d1SDavid du Colombier LONG $12345 2843e12c5d1SDavid du Colombier.P2 2853e12c5d1SDavid du Colombierplaces the long 12345 (base 10) 2863e12c5d1SDavid du Colombierin the instruction stream. 2877dd7cddfSDavid du Colombier(On most machines, 2887dd7cddfSDavid du Colombierthe only such operator is 2893e12c5d1SDavid du Colombier.CW WORD 2907dd7cddfSDavid du Colombierand it lays down 32-bit quantities. 2917dd7cddfSDavid du ColombierThe 386 has all three: 2927dd7cddfSDavid du Colombier.CW LONG , 2937dd7cddfSDavid du Colombier.CW WORD , 2947dd7cddfSDavid du Colombierand 2957dd7cddfSDavid du Colombier.CW BYTE . 296426d2b71SDavid du ColombierThe AMD64 adds 297426d2b71SDavid du Colombier.CW QUAD 298426d2b71SDavid du Colombierto that for 64-bit values. 2997dd7cddfSDavid du ColombierThe 960 has only one, 3007dd7cddfSDavid du Colombier.CW LONG .) 3013e12c5d1SDavid du Colombier.PP 3023e12c5d1SDavid du ColombierPlacing information in the data section is more painful. 3033e12c5d1SDavid du ColombierThe pseudo-instruction 3043e12c5d1SDavid du Colombier.CW DATA 3053e12c5d1SDavid du Colombierdoes the work, given two arguments: an address at which to place the item, 3063e12c5d1SDavid du Colombierincluding its size, 3073e12c5d1SDavid du Colombierand the value to place there. For example, to define a character array 3083e12c5d1SDavid du Colombier.CW array 3093e12c5d1SDavid du Colombiercontaining the characters 3103e12c5d1SDavid du Colombier.CW abc 3113e12c5d1SDavid du Colombierand a terminating null: 3123e12c5d1SDavid du Colombier.P1 3133e12c5d1SDavid du Colombier DATA array+0(SB)/1, $'a' 3143e12c5d1SDavid du Colombier DATA array+1(SB)/1, $'b' 3153e12c5d1SDavid du Colombier DATA array+2(SB)/1, $'c' 3163e12c5d1SDavid du Colombier GLOBL array(SB), $4 3173e12c5d1SDavid du Colombier.P2 318219b2ee8SDavid du Colombieror 319219b2ee8SDavid du Colombier.P1 320219b2ee8SDavid du Colombier DATA array+0(SB)/4, $"abc\ez" 321219b2ee8SDavid du Colombier GLOBL array(SB), $4 322219b2ee8SDavid du Colombier.P2 323219b2ee8SDavid du ColombierThe 3243e12c5d1SDavid du Colombier.CW /1 3253e12c5d1SDavid du Colombierdefines the number of bytes to define, 3263e12c5d1SDavid du Colombier.CW GLOBL 3273e12c5d1SDavid du Colombiermakes the symbol global, and the 3283e12c5d1SDavid du Colombier.CW $4 3293e12c5d1SDavid du Colombiersays how many bytes the symbol occupies. 3303e12c5d1SDavid du ColombierUninitialized data is zeroed automatically. 331219b2ee8SDavid du ColombierThe character 332219b2ee8SDavid du Colombier.CW \ez 333219b2ee8SDavid du Colombieris equivalent to the C 334219b2ee8SDavid du Colombier.CW \e0. 335219b2ee8SDavid du ColombierThe string in a 336219b2ee8SDavid du Colombier.CW DATA 337219b2ee8SDavid du Colombierstatement may contain a maximum of eight bytes; 338219b2ee8SDavid du Colombierbuild larger strings piecewise. 339219b2ee8SDavid du ColombierTwo pseudo-instructions, 340219b2ee8SDavid du Colombier.CW DYNT 341219b2ee8SDavid du Colombierand 342219b2ee8SDavid du Colombier.CW INIT , 3437dd7cddfSDavid du Colombierallow the (obsolete) Alef compilers to build dynamic type information during the load 344219b2ee8SDavid du Colombierphase. 345219b2ee8SDavid du ColombierThe 346219b2ee8SDavid du Colombier.CW DYNT 347219b2ee8SDavid du Colombierpseudo-instruction has two forms: 348219b2ee8SDavid du Colombier.P1 349219b2ee8SDavid du Colombier DYNT , ALEF_SI_5+0(SB) 350219b2ee8SDavid du Colombier DYNT ALEF_AS+0(SB), ALEF_SI_5+0(SB) 351219b2ee8SDavid du Colombier.P2 352219b2ee8SDavid du ColombierIn the first form, 353219b2ee8SDavid du Colombier.CW DYNT 354219b2ee8SDavid du Colombierdefines the symbol to be a small unique integer constant, chosen by the loader, 355219b2ee8SDavid du Colombierwhich is some multiple of the word size. In the second form, 356219b2ee8SDavid du Colombier.CW DYNT 357219b2ee8SDavid du Colombierdefines the second symbol in the same way, 358219b2ee8SDavid du Colombierplaces the address of the most recently 359219b2ee8SDavid du Colombierdefined text symbol in the array specified by the first symbol at the 360219b2ee8SDavid du Colombierindex defined by the value of the second symbol, 361219b2ee8SDavid du Colombierand then adjusts the size of the array accordingly. 362219b2ee8SDavid du Colombier.PP 363219b2ee8SDavid du ColombierThe 364219b2ee8SDavid du Colombier.CW INIT 365219b2ee8SDavid du Colombierpseudo-instruction takes the same parameters as a 366219b2ee8SDavid du Colombier.CW DATA 367219b2ee8SDavid du Colombierstatement. Its symbol is used as the base of an array and the 368219b2ee8SDavid du Colombierdata item is installed in the array at the offset specified by the most recent 369219b2ee8SDavid du Colombier.CW DYNT 370219b2ee8SDavid du Colombierpseudo-instruction. 371219b2ee8SDavid du ColombierThe size of the array is adjusted accordingly. 372219b2ee8SDavid du ColombierThe 373219b2ee8SDavid du Colombier.CW DYNT 374219b2ee8SDavid du Colombierand 375219b2ee8SDavid du Colombier.CW INIT 376219b2ee8SDavid du Colombierpseudo-instructions are not implemented on the 68020. 3773e12c5d1SDavid du Colombier.SH 3783e12c5d1SDavid du ColombierDefining a procedure 3793e12c5d1SDavid du Colombier.PP 3803e12c5d1SDavid du ColombierEntry points are defined by the pseudo-operation 3813e12c5d1SDavid du Colombier.CW TEXT , 3823e12c5d1SDavid du Colombierwhich takes as arguments the name of the procedure (including the ubiquitous 3833e12c5d1SDavid du Colombier.CW (SB) ) 3843e12c5d1SDavid du Colombierand the number of bytes of automatic storage to pre-allocate on the stack, 3853e12c5d1SDavid du Colombierwhich will usually be zero when writing assembly language programs. 3867dd7cddfSDavid du ColombierOn machines with a link register, such as the MIPS and SPARC, 3877dd7cddfSDavid du Colombierthe special value -4 instructs the loader to generate no PC save 388219b2ee8SDavid du Colombierand restore instructions, even if the function is not a leaf. 3893e12c5d1SDavid du ColombierHere is a complete procedure that returns the sum 3903e12c5d1SDavid du Colombierof its two arguments: 3913e12c5d1SDavid du Colombier.P1 3923e12c5d1SDavid du ColombierTEXT sum(SB), $0 3933e12c5d1SDavid du Colombier MOVL arg1+0(FP), R0 3943e12c5d1SDavid du Colombier ADDL arg2+4(FP), R0 3953e12c5d1SDavid du Colombier RTS 3963e12c5d1SDavid du Colombier.P2 3973e12c5d1SDavid du ColombierAn optional middle argument 3983e12c5d1SDavid du Colombierto the 3993e12c5d1SDavid du Colombier.CW TEXT 400219b2ee8SDavid du Colombierpseudo-op is a bit field of options to the loader. 401219b2ee8SDavid du ColombierSetting the 1 bit suspends profiling the function when profiling is enabled for the rest of 402219b2ee8SDavid du Colombierthe program. 4033e12c5d1SDavid du ColombierFor example, 4043e12c5d1SDavid du Colombier.P1 4053e12c5d1SDavid du ColombierTEXT sum(SB), 1, $0 4063e12c5d1SDavid du Colombier MOVL arg1+0(FP), R0 4073e12c5d1SDavid du Colombier ADDL arg2+4(FP), R0 4083e12c5d1SDavid du Colombier RTS 4093e12c5d1SDavid du Colombier.P2 4103e12c5d1SDavid du Colombierwill not be profiled; the first version above would be. 4113e12c5d1SDavid du ColombierSubroutines with peculiar state, such as system call routines, 4123e12c5d1SDavid du Colombiershould not be profiled. 4133e12c5d1SDavid du Colombier.PP 414219b2ee8SDavid du ColombierSetting the 2 bit allows multiple definitions of the same 415219b2ee8SDavid du Colombier.CW TEXT 416219b2ee8SDavid du Colombiersymbol in a program; the loader will place only one such function in the image. 4177dd7cddfSDavid du ColombierIt was emitted only by the Alef compilers. 418219b2ee8SDavid du Colombier.PP 4193e12c5d1SDavid du ColombierSubroutines to be called from C should place their result in 4203e12c5d1SDavid du Colombier.CW R0 , 4213e12c5d1SDavid du Colombiereven if it is an address. 4223e12c5d1SDavid du ColombierFloating point values are returned in 4233e12c5d1SDavid du Colombier.CW F0 . 4243e12c5d1SDavid du ColombierFunctions that return a structure to a C program 4253e12c5d1SDavid du Colombierreceive as their first argument the address of the location to 4263e12c5d1SDavid du Colombierstore the result; 4273e12c5d1SDavid du Colombier.CW R0 4283e12c5d1SDavid du Colombieris unused in the calling protocol for such procedures. 4293e12c5d1SDavid du ColombierA subroutine is responsible for saving its own registers, 4303e12c5d1SDavid du Colombierand therefore is free to use any registers without saving them (``caller saves''). 4313e12c5d1SDavid du Colombier.CW A6 4323e12c5d1SDavid du Colombierand 4333e12c5d1SDavid du Colombier.CW A7 4343e12c5d1SDavid du Colombierare the exceptions as described above. 4353e12c5d1SDavid du Colombier.SH 4363e12c5d1SDavid du ColombierWhen in doubt 4373e12c5d1SDavid du Colombier.PP 4383e12c5d1SDavid du ColombierIf you get confused, try using the 4393e12c5d1SDavid du Colombier.CW -S 4403e12c5d1SDavid du Colombieroption to 4413e12c5d1SDavid du Colombier.CW 2c 4423e12c5d1SDavid du Colombierand compiling a sample program. 4433e12c5d1SDavid du ColombierThe standard output is valid input to the assembler. 4443e12c5d1SDavid du Colombier.SH 4453e12c5d1SDavid du ColombierInstructions 4463e12c5d1SDavid du Colombier.PP 4473e12c5d1SDavid du ColombierThe instruction set of the assembler is not identical to that 4483e12c5d1SDavid du Colombierof the machine. 4493e12c5d1SDavid du ColombierIt is chosen to match what the compiler generates, augmented 4503e12c5d1SDavid du Colombierslightly by specific needs of the operating system. 4513e12c5d1SDavid du ColombierFor example, 4523e12c5d1SDavid du Colombier.CW 2a 4533e12c5d1SDavid du Colombierdoes not distinguish between the various forms of 4543e12c5d1SDavid du Colombier.CW MOVE 4553e12c5d1SDavid du Colombierinstruction: move quick, move address, etc. Instead the context 4563e12c5d1SDavid du Colombierdoes the job. For example, 4573e12c5d1SDavid du Colombier.P1 4583e12c5d1SDavid du Colombier MOVL $1, R1 4593e12c5d1SDavid du Colombier MOVL A0, R2 4603e12c5d1SDavid du Colombier MOVW SR, R3 4613e12c5d1SDavid du Colombier.P2 4623e12c5d1SDavid du Colombiergenerates official 4633e12c5d1SDavid du Colombier.CW MOVEQ , 4643e12c5d1SDavid du Colombier.CW MOVEA , 4653e12c5d1SDavid du Colombierand 4663e12c5d1SDavid du Colombier.CW MOVESR 4673e12c5d1SDavid du Colombierinstructions. 4683e12c5d1SDavid du ColombierA number of instructions do not have the syntax necessary to specify 4693e12c5d1SDavid du Colombiertheir entire capabilities. Notable examples are the bitfield 4703e12c5d1SDavid du Colombierinstructions, the 4713e12c5d1SDavid du Colombiermultiply and divide instructions, etc. 4723e12c5d1SDavid du ColombierFor a complete set of generated instruction names (in 4733e12c5d1SDavid du Colombier.CW 2a 4743e12c5d1SDavid du Colombiernotation, not Motorola's) see the file 4753e12c5d1SDavid du Colombier.CW /sys/src/cmd/2c/2.out.h . 4763e12c5d1SDavid du ColombierDespite its name, this file contains an enumeration of the 4773e12c5d1SDavid du Colombierinstructions that appear in the intermediate files generated 4783e12c5d1SDavid du Colombierby the compiler, which correspond exactly to lines of assembly language. 4793e12c5d1SDavid du Colombier.SH 480219b2ee8SDavid du ColombierLaying down instructions 4813e12c5d1SDavid du Colombier.PP 482219b2ee8SDavid du ColombierThe loader modifies the code produced by the assembler and compiler. 483219b2ee8SDavid du ColombierIt folds branches, 484219b2ee8SDavid du Colombiercopies short sequences of code to eliminate branches, 485219b2ee8SDavid du Colombierand discards unreachable code. 486219b2ee8SDavid du ColombierThe first instruction of every function is assumed to be reachable. 487219b2ee8SDavid du ColombierThe pseudo-instruction 488219b2ee8SDavid du Colombier.CW NOP , 489219b2ee8SDavid du Colombierwhich you may see in compiler output, 490219b2ee8SDavid du Colombiermeans no instruction at all, rather than an instruction that does nothing. 491219b2ee8SDavid du ColombierThe loader discards all 492219b2ee8SDavid du Colombier.CW NOP 's. 493219b2ee8SDavid du Colombier.PP 494219b2ee8SDavid du ColombierTo generate a true 495219b2ee8SDavid du Colombier.CW NOP 496219b2ee8SDavid du Colombierinstruction, or any other instruction not known to the assembler, use a 497219b2ee8SDavid du Colombier.CW WORD 498219b2ee8SDavid du Colombierpseudo-instruction. 499219b2ee8SDavid du ColombierSuch instructions on RISCs are not scheduled by the loader and must have 500219b2ee8SDavid du Colombiertheir delay slots filled manually. 5013e12c5d1SDavid du Colombier.SH 5023e12c5d1SDavid du ColombierMIPS 5033e12c5d1SDavid du Colombier.PP 5043e12c5d1SDavid du ColombierThe registers are only addressed by number: 5053e12c5d1SDavid du Colombier.CW R0 5063e12c5d1SDavid du Colombierthrough 5073e12c5d1SDavid du Colombier.CW R31 . 5083e12c5d1SDavid du Colombier.CW R29 5093e12c5d1SDavid du Colombieris the stack pointer; 5103e12c5d1SDavid du Colombier.CW R30 5113e12c5d1SDavid du Colombieris used as the static base pointer, the analogue of 5123e12c5d1SDavid du Colombier.CW A6 5133e12c5d1SDavid du Colombieron the 68020. 5143e12c5d1SDavid du ColombierIts value is the address of the global symbol 5153e12c5d1SDavid du Colombier.CW setR30(SB) . 5163e12c5d1SDavid du ColombierThe register holding returned values from subroutines is 5173e12c5d1SDavid du Colombier.CW R1 . 5183e12c5d1SDavid du ColombierWhen a function is called, space for the first argument 5193e12c5d1SDavid du Colombieris reserved at 5203e12c5d1SDavid du Colombier.CW 0(FP) 521219b2ee8SDavid du Colombierbut in C (not Alef) the value is passed in 522219b2ee8SDavid du Colombier.CW R1 523219b2ee8SDavid du Colombierinstead. 5243e12c5d1SDavid du Colombier.PP 5253e12c5d1SDavid du ColombierThe loader uses 5263e12c5d1SDavid du Colombier.CW R28 5273e12c5d1SDavid du Colombieras a temporary. The system uses 5283e12c5d1SDavid du Colombier.CW R26 5293e12c5d1SDavid du Colombierand 5303e12c5d1SDavid du Colombier.CW R27 531219b2ee8SDavid du Colombieras interrupt-time temporaries. Therefore none of these registers 532219b2ee8SDavid du Colombiershould be used in user code. 5333e12c5d1SDavid du Colombier.PP 5343e12c5d1SDavid du ColombierThe control registers are not known to the assembler. 5353e12c5d1SDavid du ColombierInstead they are numbered registers 5363e12c5d1SDavid du Colombier.CW M0 , 5373e12c5d1SDavid du Colombier.CW M1 , 5383e12c5d1SDavid du Colombieretc. 5393e12c5d1SDavid du ColombierUse this trick to access, say, 540219b2ee8SDavid du Colombier.CW STATUS : 5413e12c5d1SDavid du Colombier.P1 542219b2ee8SDavid du Colombier#define STATUS 12 543219b2ee8SDavid du Colombier MOVW M(STATUS), R1 5443e12c5d1SDavid du Colombier.P2 5453e12c5d1SDavid du Colombier.PP 5463e12c5d1SDavid du ColombierFloating point registers are called 5473e12c5d1SDavid du Colombier.CW F0 5483e12c5d1SDavid du Colombierthrough 5493e12c5d1SDavid du Colombier.CW F31 . 5503e12c5d1SDavid du ColombierBy convention, 5513e12c5d1SDavid du Colombier.CW F24 5523e12c5d1SDavid du Colombiermust be initialized to the value 0.0, 5533e12c5d1SDavid du Colombier.CW F26 5543e12c5d1SDavid du Colombierto 0.5, 5553e12c5d1SDavid du Colombier.CW F28 5563e12c5d1SDavid du Colombierto 1.0, and 5573e12c5d1SDavid du Colombier.CW F30 558219b2ee8SDavid du Colombierto 2.0; 559219b2ee8SDavid du Colombierthis is done by the operating system. 5603e12c5d1SDavid du Colombier.PP 561219b2ee8SDavid du ColombierThe instructions and their syntax are different from those of the manufacturer's 562219b2ee8SDavid du Colombiermanual. 5633e12c5d1SDavid du ColombierThere are no 5643e12c5d1SDavid du Colombier.CW lui 5653e12c5d1SDavid du Colombierand kin; instead there are 5663e12c5d1SDavid du Colombier.CW MOVW 5673e12c5d1SDavid du Colombier(move word), 5683e12c5d1SDavid du Colombier.CW MOVH 5693e12c5d1SDavid du Colombier(move halfword), 5703e12c5d1SDavid du Colombierand 5713e12c5d1SDavid du Colombier.CW MOVB 5723e12c5d1SDavid du Colombier(move byte) pseudo-instructions. If the operand is unsigned, the instructions 5733e12c5d1SDavid du Colombierare 5743e12c5d1SDavid du Colombier.CW MOVHU 5753e12c5d1SDavid du Colombierand 5763e12c5d1SDavid du Colombier.CW MOVBU . 5773e12c5d1SDavid du ColombierThe order of operands is from left to right in dataflow order, just as 578219b2ee8SDavid du Colombieron the 68020 but not as in MIPS documentation. 579219b2ee8SDavid du ColombierThis means that the 5803e12c5d1SDavid du Colombier.CW Bcond 5813e12c5d1SDavid du Colombierinstructions are reversed with respect to the book; for example, a 5823e12c5d1SDavid du Colombier.CW va 5833e12c5d1SDavid du Colombier.CW BGTZ 5843e12c5d1SDavid du Colombiergenerates a MIPS 5853e12c5d1SDavid du Colombier.CW bltz 5863e12c5d1SDavid du Colombierinstruction. 5873e12c5d1SDavid du Colombier.PP 588219b2ee8SDavid du ColombierThe assembler is for the R2000, R3000, and most of the R4000 and R6000 architectures. 589219b2ee8SDavid du ColombierIt understands the 64-bit instructions 590219b2ee8SDavid du Colombier.CW MOVV , 591219b2ee8SDavid du Colombier.CW MOVVL , 592219b2ee8SDavid du Colombier.CW ADDV , 593219b2ee8SDavid du Colombier.CW ADDVU , 594219b2ee8SDavid du Colombier.CW SUBV , 595219b2ee8SDavid du Colombier.CW SUBVU , 596219b2ee8SDavid du Colombier.CW MULV , 597219b2ee8SDavid du Colombier.CW MULVU , 598219b2ee8SDavid du Colombier.CW DIVV , 599219b2ee8SDavid du Colombier.CW DIVVU , 600219b2ee8SDavid du Colombier.CW SLLV , 601219b2ee8SDavid du Colombier.CW SRLV , 602219b2ee8SDavid du Colombierand 603219b2ee8SDavid du Colombier.CW SRAV . 604219b2ee8SDavid du ColombierThe assembler does not have any cache, load-linked, or store-conditional instructions. 605219b2ee8SDavid du Colombier.PP 606219b2ee8SDavid du ColombierSome assembler instructions are expanded into multiple instructions by the loader. 607219b2ee8SDavid du ColombierFor example the loader may convert the load of a 32 bit constant into an 608219b2ee8SDavid du Colombier.CW lui 609219b2ee8SDavid du Colombierfollowed by an 610219b2ee8SDavid du Colombier.CW ori . 611219b2ee8SDavid du Colombier.PP 612219b2ee8SDavid du ColombierAssembler instructions should be laid out as if there 613219b2ee8SDavid du Colombierwere no load, branch, or floating point compare delay slots; 614219b2ee8SDavid du Colombierthe loader will rearrange\(em\f2schedule\f1\(emthe instructions 615219b2ee8SDavid du Colombierto guarantee correctness and improve performance. 616219b2ee8SDavid du ColombierThe only exception is that the correct scheduling of instructions 617219b2ee8SDavid du Colombierthat use control registers varies from model to model of machine 618219b2ee8SDavid du Colombier(and is often undocumented) so you should schedule such instructions 619219b2ee8SDavid du Colombierby hand to guarantee correct behavior. 620219b2ee8SDavid du ColombierThe loader generates 6213e12c5d1SDavid du Colombier.P1 6223e12c5d1SDavid du Colombier NOR R0, R0, R0 6233e12c5d1SDavid du Colombier.P2 624219b2ee8SDavid du Colombierwhen it needs a true no-op instruction. 625219b2ee8SDavid du ColombierUse exactly this instruction when scheduling code manually; 626219b2ee8SDavid du Colombierthe loader recognizes it and schedules the code before it and after it independently. Also, 627219b2ee8SDavid du Colombier.CW WORD 628219b2ee8SDavid du Colombierpseudo-ops are scheduled like no-ops. 629219b2ee8SDavid du Colombier.PP 630219b2ee8SDavid du ColombierThe 631219b2ee8SDavid du Colombier.CW NOSCHED 632219b2ee8SDavid du Colombierpseudo-op disables instruction scheduling 633219b2ee8SDavid du Colombier(scheduling is enabled by default); 634219b2ee8SDavid du Colombier.CW SCHED 635219b2ee8SDavid du Colombierre-enables it. 636219b2ee8SDavid du ColombierBranch folding, code copying, and dead code elimination are 637219b2ee8SDavid du Colombierdisabled for instructions that are not scheduled. 6383e12c5d1SDavid du Colombier.SH 6393e12c5d1SDavid du ColombierSPARC 6403e12c5d1SDavid du Colombier.PP 6413e12c5d1SDavid du ColombierOnce you understand the Plan 9 model for the MIPS, the SPARC is familiar. 6423e12c5d1SDavid du ColombierRegisters have numerical names only: 6433e12c5d1SDavid du Colombier.CW R0 6443e12c5d1SDavid du Colombierthrough 6453e12c5d1SDavid du Colombier.CW R31 . 646219b2ee8SDavid du ColombierForget about register windows: Plan 9 doesn't use them at all. 6473e12c5d1SDavid du ColombierThe machine has 32 global registers, period. 6483e12c5d1SDavid du Colombier.CW R1 649219b2ee8SDavid du Colombier[sic] is the stack pointer. 6503e12c5d1SDavid du Colombier.CW R2 6513e12c5d1SDavid du Colombieris the static base register, with value the address of 6523e12c5d1SDavid du Colombier.CW setSB(SB) . 6533e12c5d1SDavid du Colombier.CW R7 6543e12c5d1SDavid du Colombieris the return register and also the register holding the first 655219b2ee8SDavid du Colombierargument to a C (not Alef) function, again with space reserved at 6563e12c5d1SDavid du Colombier.CW 0(FP) . 6573e12c5d1SDavid du Colombier.CW R14 6583e12c5d1SDavid du Colombieris the loader temporary. 6593e12c5d1SDavid du Colombier.PP 6603e12c5d1SDavid du ColombierFloating-point registers are exactly as on the MIPS. 6613e12c5d1SDavid du Colombier.PP 6623e12c5d1SDavid du ColombierThe control registers are known by names such as 6633e12c5d1SDavid du Colombier.CW FSR . 6643e12c5d1SDavid du ColombierThe instructions to access these registers are 6653e12c5d1SDavid du Colombier.CW MOVW 6663e12c5d1SDavid du Colombierinstructions, for example 6673e12c5d1SDavid du Colombier.P1 6683e12c5d1SDavid du Colombier MOVW Y, R8 6693e12c5d1SDavid du Colombier.P2 670219b2ee8SDavid du Colombierfor the SPARC instruction 6713e12c5d1SDavid du Colombier.P1 6723e12c5d1SDavid du Colombier rdy %r8 6733e12c5d1SDavid du Colombier.P2 6743e12c5d1SDavid du Colombier.PP 6753e12c5d1SDavid du ColombierMove instructions are similar to those on the MIPS: pseudo-operations 6763e12c5d1SDavid du Colombierthat turn into appropriate sequences of 6773e12c5d1SDavid du Colombier.CW sethi 6783e12c5d1SDavid du Colombierinstructions, adds, etc. 6793e12c5d1SDavid du ColombierInstructions read from left to right. Because the arguments are 6803e12c5d1SDavid du Colombierflipped to 6813e12c5d1SDavid du Colombier.CW SUBCC , 6823e12c5d1SDavid du Colombierthe condition codes are not inverted as on the MIPS. 6833e12c5d1SDavid du Colombier.PP 6843e12c5d1SDavid du ColombierThe syntax for the ASI stuff is, for example to move a word from ASI 2: 6853e12c5d1SDavid du Colombier.P1 6863e12c5d1SDavid du Colombier MOVW (R7, 2), R8 6873e12c5d1SDavid du Colombier.P2 6883e12c5d1SDavid du ColombierThe syntax for double indexing is 6893e12c5d1SDavid du Colombier.P1 6903e12c5d1SDavid du Colombier MOVW (R7+R8), R9 6913e12c5d1SDavid du Colombier.P2 6923e12c5d1SDavid du Colombier.PP 693219b2ee8SDavid du ColombierThe SPARC's instruction scheduling is similar to the MIPS's. 694219b2ee8SDavid du ColombierThe official no-op instruction is: 695219b2ee8SDavid du Colombier.P1 696219b2ee8SDavid du Colombier ORN R0, R0, R0 697219b2ee8SDavid du Colombier.P2 6983e12c5d1SDavid du Colombier.SH 6993e12c5d1SDavid du Colombieri960 7003e12c5d1SDavid du Colombier.PP 7013e12c5d1SDavid du ColombierRegisters are numbered 7023e12c5d1SDavid du Colombier.CW R0 7033e12c5d1SDavid du Colombierthrough 7043e12c5d1SDavid du Colombier.CW R31 . 7053e12c5d1SDavid du ColombierStack pointer is 7063e12c5d1SDavid du Colombier.CW R29 ; 7073e12c5d1SDavid du Colombierreturn register is 7083e12c5d1SDavid du Colombier.CW R4 ; 7093e12c5d1SDavid du Colombierstatic base is 7103e12c5d1SDavid du Colombier.CW R28 ; 7113e12c5d1SDavid du Colombierit is initialized to the address of 7123e12c5d1SDavid du Colombier.CW setSB(SB) . 7133e12c5d1SDavid du Colombier.CW R3 7143e12c5d1SDavid du Colombiermust be zero; this should be done manually early in execution by 7153e12c5d1SDavid du Colombier.P1 7163e12c5d1SDavid du Colombier SUBO R3, R3 7173e12c5d1SDavid du Colombier.P2 7183e12c5d1SDavid du Colombier.CW R27 7193e12c5d1SDavid du Colombieris the loader temporary. 7203e12c5d1SDavid du Colombier.PP 7213e12c5d1SDavid du ColombierThere is no support for floating point. 7223e12c5d1SDavid du Colombier.PP 7233e12c5d1SDavid du ColombierThe Intel calling convention is not supported and cannot be used; use 7243e12c5d1SDavid du Colombier.CW BAL 7253e12c5d1SDavid du Colombierinstead. 7263e12c5d1SDavid du ColombierInstructions are mostly as in the book. The major change is that 7273e12c5d1SDavid du Colombier.CW LOAD 7283e12c5d1SDavid du Colombierand 7293e12c5d1SDavid du Colombier.CW STORE 7303e12c5d1SDavid du Colombierare both called 7313e12c5d1SDavid du Colombier.CW MOV . 7323e12c5d1SDavid du ColombierThe extension character for 7333e12c5d1SDavid du Colombier.CW MOV 7343e12c5d1SDavid du Colombieris as in the manual: 7353e12c5d1SDavid du Colombier.CW O 7363e12c5d1SDavid du Colombierfor ordinal, 7373e12c5d1SDavid du Colombier.CW W 7383e12c5d1SDavid du Colombierfor signed, etc. 7393e12c5d1SDavid du Colombier.SH 7403e12c5d1SDavid du Colombieri386 7413e12c5d1SDavid du Colombier.PP 7423e12c5d1SDavid du ColombierThe assembler assumes 32-bit protected mode. 7433e12c5d1SDavid du ColombierThe register names are 7443e12c5d1SDavid du Colombier.CW SP , 7453e12c5d1SDavid du Colombier.CW AX , 7463e12c5d1SDavid du Colombier.CW BX , 7473e12c5d1SDavid du Colombier.CW CX , 7483e12c5d1SDavid du Colombier.CW DX , 7493e12c5d1SDavid du Colombier.CW BP , 7503e12c5d1SDavid du Colombier.CW DI , 7513e12c5d1SDavid du Colombierand 7523e12c5d1SDavid du Colombier.CW SI . 753219b2ee8SDavid du ColombierThe stack pointer (not a pseudo-register) is 7543e12c5d1SDavid du Colombier.CW SP 7553e12c5d1SDavid du Colombierand the return register is 7563e12c5d1SDavid du Colombier.CW AX . 757219b2ee8SDavid du ColombierThere is no physical frame pointer but, as for the MIPS, 7583e12c5d1SDavid du Colombier.CW FP 7593e12c5d1SDavid du Colombieris a pseudo-register that acts as 760219b2ee8SDavid du Colombiera frame pointer. 7613e12c5d1SDavid du Colombier.PP 7623e12c5d1SDavid du ColombierOpcode names are mostly the same as those listed in the Intel manual 7633e12c5d1SDavid du Colombierwith an 7643e12c5d1SDavid du Colombier.CW L , 7653e12c5d1SDavid du Colombier.CW W , 7663e12c5d1SDavid du Colombieror 7673e12c5d1SDavid du Colombier.CW B 7683e12c5d1SDavid du Colombierappended to identify 32-bit, 7693e12c5d1SDavid du Colombier16-bit, and 8-bit operations. 7703e12c5d1SDavid du ColombierThe exceptions are loads, stores, and conditionals. 7713e12c5d1SDavid du ColombierAll load and store opcodes to and from general registers, special registers 7723e12c5d1SDavid du Colombier(such as 7733e12c5d1SDavid du Colombier.CW CR0, 7743e12c5d1SDavid du Colombier.CW CR3, 7753e12c5d1SDavid du Colombier.CW GDTR, 7763e12c5d1SDavid du Colombier.CW IDTR, 7773e12c5d1SDavid du Colombier.CW SS, 7783e12c5d1SDavid du Colombier.CW CS, 7793e12c5d1SDavid du Colombier.CW DS, 7803e12c5d1SDavid du Colombier.CW ES, 7813e12c5d1SDavid du Colombier.CW FS, 7823e12c5d1SDavid du Colombierand 7833e12c5d1SDavid du Colombier.CW GS ) 7843e12c5d1SDavid du Colombieror memory are written 7853e12c5d1SDavid du Colombieras 7863e12c5d1SDavid du Colombier.P1 7873e12c5d1SDavid du Colombier MOV\f2x\fP src,dst 7883e12c5d1SDavid du Colombier.P2 7893e12c5d1SDavid du Colombierwhere 7903e12c5d1SDavid du Colombier.I x 7913e12c5d1SDavid du Colombieris 7923e12c5d1SDavid du Colombier.CW L , 7933e12c5d1SDavid du Colombier.CW W , 7943e12c5d1SDavid du Colombieror 7953e12c5d1SDavid du Colombier.CW B . 7963e12c5d1SDavid du ColombierThus to get 7973e12c5d1SDavid du Colombier.CW AL 7983e12c5d1SDavid du Colombieruse a 7993e12c5d1SDavid du Colombier.CW MOVB 8003e12c5d1SDavid du Colombierinstruction. If you need to access 8013e12c5d1SDavid du Colombier.CW AH , 8023e12c5d1SDavid du Colombieryou must mention it explicitly in a 8033e12c5d1SDavid du Colombier.CW MOVB : 8043e12c5d1SDavid du Colombier.P1 8053e12c5d1SDavid du Colombier MOVB AH, BX 8063e12c5d1SDavid du Colombier.P2 807219b2ee8SDavid du ColombierThere are many examples of illegal moves, for example, 8083e12c5d1SDavid du Colombier.P1 8093e12c5d1SDavid du Colombier MOVB BP, DI 8103e12c5d1SDavid du Colombier.P2 811219b2ee8SDavid du Colombierthat the loader actually implements as pseudo-operations. 8123e12c5d1SDavid du Colombier.PP 8133e12c5d1SDavid du ColombierThe names of conditions in all conditional instructions 8143e12c5d1SDavid du Colombier.CW J , ( 8153e12c5d1SDavid du Colombier.CW SET ) 8163e12c5d1SDavid du Colombierfollow the conventions of the 68020 instead of those of the Intel 8173e12c5d1SDavid du Colombierassembler: 8183e12c5d1SDavid du Colombier.CW JOS , 8193e12c5d1SDavid du Colombier.CW JOC , 8203e12c5d1SDavid du Colombier.CW JCS , 8213e12c5d1SDavid du Colombier.CW JCC , 8223e12c5d1SDavid du Colombier.CW JEQ , 8233e12c5d1SDavid du Colombier.CW JNE , 8243e12c5d1SDavid du Colombier.CW JLS , 8253e12c5d1SDavid du Colombier.CW JHI , 8263e12c5d1SDavid du Colombier.CW JMI , 8273e12c5d1SDavid du Colombier.CW JPL , 8283e12c5d1SDavid du Colombier.CW JPS , 8293e12c5d1SDavid du Colombier.CW JPC , 8303e12c5d1SDavid du Colombier.CW JLT , 8313e12c5d1SDavid du Colombier.CW JGE , 8323e12c5d1SDavid du Colombier.CW JLE , 8333e12c5d1SDavid du Colombierand 8343e12c5d1SDavid du Colombier.CW JGT 8353e12c5d1SDavid du Colombierinstead of 8363e12c5d1SDavid du Colombier.CW JO , 8373e12c5d1SDavid du Colombier.CW JNO , 8383e12c5d1SDavid du Colombier.CW JB , 8393e12c5d1SDavid du Colombier.CW JNB , 8403e12c5d1SDavid du Colombier.CW JZ , 8413e12c5d1SDavid du Colombier.CW JNZ , 8423e12c5d1SDavid du Colombier.CW JBE , 8433e12c5d1SDavid du Colombier.CW JNBE , 8443e12c5d1SDavid du Colombier.CW JS , 8453e12c5d1SDavid du Colombier.CW JNS , 8463e12c5d1SDavid du Colombier.CW JP , 8473e12c5d1SDavid du Colombier.CW JNP , 8483e12c5d1SDavid du Colombier.CW JL , 8493e12c5d1SDavid du Colombier.CW JNL , 8503e12c5d1SDavid du Colombier.CW JLE , 8513e12c5d1SDavid du Colombierand 8523e12c5d1SDavid du Colombier.CW JNLE . 8533e12c5d1SDavid du Colombier.PP 8543e12c5d1SDavid du ColombierThe addressing modes have syntax like 8553e12c5d1SDavid du Colombier.CW AX , 8563e12c5d1SDavid du Colombier.CW (AX) , 8573e12c5d1SDavid du Colombier.CW (AX)(BX*4) , 8583e12c5d1SDavid du Colombier.CW 10(AX) , 8593e12c5d1SDavid du Colombierand 8603e12c5d1SDavid du Colombier.CW 10(AX)(BX*4) . 8613e12c5d1SDavid du ColombierThe offsets from 8623e12c5d1SDavid du Colombier.CW AX 8633e12c5d1SDavid du Colombiercan be replaced by offsets from 8643e12c5d1SDavid du Colombier.CW FP 8653e12c5d1SDavid du Colombieror 8663e12c5d1SDavid du Colombier.CW SB 8673e12c5d1SDavid du Colombierto access names, for example 8683e12c5d1SDavid du Colombier.CW extern+5(SB)(AX*2) . 8693e12c5d1SDavid du Colombier.PP 8703e12c5d1SDavid du ColombierOther notes: Non-relative 8713e12c5d1SDavid du Colombier.CW JMP 8723e12c5d1SDavid du Colombierand 8733e12c5d1SDavid du Colombier.CW CALL 8743e12c5d1SDavid du Colombierhave a 8753e12c5d1SDavid du Colombier.CW * 8763e12c5d1SDavid du Colombieradded to the syntax. 8773e12c5d1SDavid du ColombierOnly 8783e12c5d1SDavid du Colombier.CW LOOP , 8793e12c5d1SDavid du Colombier.CW LOOPEQ , 8803e12c5d1SDavid du Colombierand 8813e12c5d1SDavid du Colombier.CW LOOPNE 8823e12c5d1SDavid du Colombierare legal loop instructions. Only 8833e12c5d1SDavid du Colombier.CW REP 8843e12c5d1SDavid du Colombierand 8853e12c5d1SDavid du Colombier.CW REPN 8863e12c5d1SDavid du Colombierare recognized repeaters. These are not prefixes, but rather 887219b2ee8SDavid du Colombierstand-alone opcodes that precede the strings, for example 8883e12c5d1SDavid du Colombier.P1 8893e12c5d1SDavid du Colombier CLD; REP; MOVSL 8903e12c5d1SDavid du Colombier.P2 891219b2ee8SDavid du ColombierSegment override prefixes in 892219b2ee8SDavid du Colombier.CW MOD/RM 893219b2ee8SDavid du Colombierfields are not supported. 8943e12c5d1SDavid du Colombier.SH 895426d2b71SDavid du ColombierAMD64 896426d2b71SDavid du Colombier.PP 897426d2b71SDavid du ColombierThe assembler assumes 64-bit mode unless a 898426d2b71SDavid du Colombier.CW MODE 899426d2b71SDavid du Colombierpseudo-operation is given: 900426d2b71SDavid du Colombier.P1 901426d2b71SDavid du Colombier MODE $32 902426d2b71SDavid du Colombier.P2 903426d2b71SDavid du Colombierto change to 32-bit mode. 904426d2b71SDavid du ColombierThe effect is mainly to diagnose instructions that are illegal in 905426d2b71SDavid du Colombierthe given mode, but the loader will also assume 32-bit operands and addresses, 906426d2b71SDavid du Colombierand 32-bit PC values for call and return. 907426d2b71SDavid du ColombierThe assembler's conventions are similar to those for the 386, above. 908426d2b71SDavid du ColombierThe architecture provides extra fixed-point registers 909426d2b71SDavid du Colombier.CW R8 910426d2b71SDavid du Colombierto 911426d2b71SDavid du Colombier.CW R15 . 912426d2b71SDavid du ColombierAll registers are 64 bit, but instructions access low-order 8, 16 and 32 bits 913426d2b71SDavid du Colombieras described in the processor handbook. 914426d2b71SDavid du ColombierFor example, 915426d2b71SDavid du Colombier.CW MOVL 916426d2b71SDavid du Colombierto 917426d2b71SDavid du Colombier.CW AX 918426d2b71SDavid du Colombierputs a value in the low-order 32 bits and clears the top 32 bits to zero. 919426d2b71SDavid du ColombierLiteral operands are limited to signed 32 bit values, which are sign-extended 920426d2b71SDavid du Colombierto 64 bits in 64 bit operations; the exception is 921426d2b71SDavid du Colombier.CW MOVQ , 922426d2b71SDavid du Colombierwhich allows 64-bit literals. 923426d2b71SDavid du ColombierThe external registers in Plan 9's C are allocated from 924426d2b71SDavid du Colombier.CW R15 925426d2b71SDavid du Colombierdown. 926f722162aSDavid du Colombier.PP 927426d2b71SDavid du ColombierThere are many new instructions, including the MMX and XMM media instructions, 928426d2b71SDavid du Colombierand conditional move instructions. 929426d2b71SDavid du ColombierMMX registers are 930426d2b71SDavid du Colombier.CW M0 931426d2b71SDavid du Colombierto 932426d2b71SDavid du Colombier.CW M7 , 933426d2b71SDavid du Colombierand 934426d2b71SDavid du ColombierXMM registers are 935426d2b71SDavid du Colombier.CW X0 936426d2b71SDavid du Colombierto 937426d2b71SDavid du Colombier.CW X15 . 938426d2b71SDavid du ColombierAs with the 386 instruction names, 939426d2b71SDavid du Colombierall new 64-bit integer instructions, and the MMX and XMM instructions 940426d2b71SDavid du Colombieruniformly use 941426d2b71SDavid du Colombier.CW L 942426d2b71SDavid du Colombierfor `long word' (32 bits) and 943426d2b71SDavid du Colombier.CW Q 944426d2b71SDavid du Colombierfor `quad word' (64 bits). 945426d2b71SDavid du ColombierSome instructions use 946426d2b71SDavid du Colombier.CW O 947426d2b71SDavid du Colombier(`octword') for 128-bit values, where the processor handbook 948426d2b71SDavid du Colombiervariously uses 949426d2b71SDavid du Colombier.CW O 950426d2b71SDavid du Colombieror 951426d2b71SDavid du Colombier.CW DQ . 952426d2b71SDavid du ColombierThe assembler also consistently uses 953426d2b71SDavid du Colombier.CW PL 954426d2b71SDavid du Colombierfor `packed long' in 955426d2b71SDavid du ColombierXMM instructions, instead of 956426d2b71SDavid du Colombier.CW Q , 957426d2b71SDavid du Colombier.CW DQ 958426d2b71SDavid du Colombieror 959426d2b71SDavid du Colombier.CW PI . 960426d2b71SDavid du ColombierEither 961426d2b71SDavid du Colombier.CW MOVL 962426d2b71SDavid du Colombieror 963426d2b71SDavid du Colombier.CW MOVQ 964426d2b71SDavid du Colombiercan be used to move values to and from control registers, even when 965426d2b71SDavid du Colombierthe registers might be 64 bits. 966426d2b71SDavid du ColombierThe assembler often accepts the handbook's name to ease conversion 967426d2b71SDavid du Colombierof existing code (but remember that the operand order is uniformly 968426d2b71SDavid du Colombiersource then destination). 969f722162aSDavid du Colombier.PP 970426d2b71SDavid du ColombierC's 971f722162aSDavid du Colombier.CW long 972f722162aSDavid du Colombier.CW long 973426d2b71SDavid du Colombiertype is 64 bits, but passed and returned by value, not by reference. 974426d2b71SDavid du ColombierMore notably, C pointer values are 64 bits, and thus 975f722162aSDavid du Colombier.CW long 976f722162aSDavid du Colombier.CW long 977426d2b71SDavid du Colombierand 978f722162aSDavid du Colombier.CW unsigned 979f722162aSDavid du Colombier.CW long 980f722162aSDavid du Colombier.CW long 981426d2b71SDavid du Colombierare the only integer types wide enough to hold a pointer value. 982426d2b71SDavid du ColombierThe C compiler and library use the XMM floating-point instructions, not 983426d2b71SDavid du Colombierthe old 387 ones, although the latter are implemented by assembler and loader. 984426d2b71SDavid du ColombierUnlike the 386, the first integer or pointer argument is passed in a register, which is 985426d2b71SDavid du Colombier.CW BP 986426d2b71SDavid du Colombierfor an integer or pointer (it can be referred to in assembly code by the pseudonym 987426d2b71SDavid du Colombier.CW RARG ). 988426d2b71SDavid du Colombier.CW AX 989426d2b71SDavid du Colombierholds the return value from subroutines as before. 990426d2b71SDavid du ColombierFloating-point results are returned in 991426d2b71SDavid du Colombier.CW X0 , 992426d2b71SDavid du Colombieralthough currently the first floating-point parameter is not passed in a register. 993426d2b71SDavid du ColombierAll parameters less than 8 bytes in length have 8 byte slots reserved on the stack 994426d2b71SDavid du Colombierto preserve alignment and simplify variable-length argument list access, 995426d2b71SDavid du Colombierincluding the first parameter when passed in a register, 996426d2b71SDavid du Colombiereven though bytes 4 to 7 are not initialized. 99740ff8eeaSDavid du Colombier. 9987dd7cddfSDavid du Colombier.SH 9997dd7cddfSDavid du ColombierPower PC 1000219b2ee8SDavid du Colombier.PP 10017dd7cddfSDavid du ColombierThe Power PC follows the Plan 9 model set by the MIPS and SPARC, 10027dd7cddfSDavid du Colombiernot the elaborate ABIs. 10037dd7cddfSDavid du ColombierThe 32-bit instructions of the 60x and 8xx PowerPC architectures are supported; 10047dd7cddfSDavid du Colombierthere is no support for the older POWER instructions. 10057dd7cddfSDavid du ColombierRegisters are 10067dd7cddfSDavid du Colombier.CW R0 10077dd7cddfSDavid du Colombierthrough 10087dd7cddfSDavid du Colombier.CW R31 . 10097dd7cddfSDavid du Colombier.CW R0 10107dd7cddfSDavid du Colombieris initialized to zero; this is done by C start up code 10117dd7cddfSDavid du Colombierand assumed by the compiler and loader. 10127dd7cddfSDavid du Colombier.CW R1 10137dd7cddfSDavid du Colombieris the stack pointer. 10147dd7cddfSDavid du Colombier.CW R2 10157dd7cddfSDavid du Colombieris the static base register, with value the address of 10167dd7cddfSDavid du Colombier.CW setSB(SB) . 10177dd7cddfSDavid du Colombier.CW R3 10187dd7cddfSDavid du Colombieris the return register and also the register holding the first 10197dd7cddfSDavid du Colombierargument to a C function, with space reserved at 10207dd7cddfSDavid du Colombier.CW 0(FP) 10217dd7cddfSDavid du Colombieras on the MIPS. 10227dd7cddfSDavid du Colombier.CW R31 10237dd7cddfSDavid du Colombieris the loader temporary. 10247dd7cddfSDavid du ColombierThe external registers in Plan 9's C are allocated from 10257dd7cddfSDavid du Colombier.CW R30 10267dd7cddfSDavid du Colombierdown. 10277dd7cddfSDavid du Colombier.PP 10287dd7cddfSDavid du ColombierFloating point registers are called 10297dd7cddfSDavid du Colombier.CW F0 10307dd7cddfSDavid du Colombierthrough 10317dd7cddfSDavid du Colombier.CW F31 . 10327dd7cddfSDavid du ColombierBy convention, several registers are initialized 10337dd7cddfSDavid du Colombierto specific values; this is done by the operating system. 10347dd7cddfSDavid du Colombier.CW F27 10357dd7cddfSDavid du Colombiermust be initialized to the value 10367dd7cddfSDavid du Colombier.CW 0x4330000080000000 10377dd7cddfSDavid du Colombier(used by float-to-int conversion), 10387dd7cddfSDavid du Colombier.CW F28 10397dd7cddfSDavid du Colombierto the value 0.0, 10407dd7cddfSDavid du Colombier.CW F29 10417dd7cddfSDavid du Colombierto 0.5, 10427dd7cddfSDavid du Colombier.CW F30 10437dd7cddfSDavid du Colombierto 1.0, and 10447dd7cddfSDavid du Colombier.CW F31 10457dd7cddfSDavid du Colombierto 2.0. 10467dd7cddfSDavid du Colombier.PP 10477dd7cddfSDavid du ColombierAs on the MIPS and SPARC, the assembler accepts arbitrary literals 10487dd7cddfSDavid du Colombieras operands to 10497dd7cddfSDavid du Colombier.CW MOVW , 10507dd7cddfSDavid du Colombierand also to 10517dd7cddfSDavid du Colombier.CW ADD 10527dd7cddfSDavid du Colombierand others where `immediate' variants exist, 10537dd7cddfSDavid du Colombierand the loader generates sequences 10547dd7cddfSDavid du Colombierof 10557dd7cddfSDavid du Colombier.CW addi , 10567dd7cddfSDavid du Colombier.CW addis , 10577dd7cddfSDavid du Colombier.CW oris , 10587dd7cddfSDavid du Colombieretc. as required. 10597dd7cddfSDavid du ColombierThe register indirect addressing modes use the same syntax as the SPARC, 10607dd7cddfSDavid du Colombierincluding double indexing when allowed. 10617dd7cddfSDavid du Colombier.PP 10627dd7cddfSDavid du ColombierThe instruction names are generally derived from the Motorola ones, 10637dd7cddfSDavid du Colombiersubject to slight transformation: 10647dd7cddfSDavid du Colombierthe 10657dd7cddfSDavid du Colombier.CW . ' ` 10667dd7cddfSDavid du Colombiermarking the setting of condition codes is replaced by 10677dd7cddfSDavid du Colombier.CW CC , 10687dd7cddfSDavid du Colombierand when the letter 10697dd7cddfSDavid du Colombier.CW o ' ` 10707dd7cddfSDavid du Colombierrepresents `OE=1' it is replaced by 10717dd7cddfSDavid du Colombier.CW V . 10727dd7cddfSDavid du ColombierThus 10737dd7cddfSDavid du Colombier.CW add , 10747dd7cddfSDavid du Colombier.CW addo. 1075219b2ee8SDavid du Colombierand 10767dd7cddfSDavid du Colombier.CW subfzeo. 10777dd7cddfSDavid du Colombierbecome 10787dd7cddfSDavid du Colombier.CW ADD , 10797dd7cddfSDavid du Colombier.CW ADDVCC 10807dd7cddfSDavid du Colombierand 10817dd7cddfSDavid du Colombier.CW SUBFZEVCC . 10827dd7cddfSDavid du ColombierAs well as the three-operand conditional branch instruction 10837dd7cddfSDavid du Colombier.CW BC , 10847dd7cddfSDavid du Colombierthe assembler provides pseudo-instructions for the common cases: 10857dd7cddfSDavid du Colombier.CW BEQ , 10867dd7cddfSDavid du Colombier.CW BNE , 10877dd7cddfSDavid du Colombier.CW BGT , 10887dd7cddfSDavid du Colombier.CW BGE , 10897dd7cddfSDavid du Colombier.CW BLT , 10907dd7cddfSDavid du Colombier.CW BLE , 10917dd7cddfSDavid du Colombier.CW BVC , 10927dd7cddfSDavid du Colombierand 10937dd7cddfSDavid du Colombier.CW BVS . 10947dd7cddfSDavid du ColombierThe unconditional branch instruction is 10957dd7cddfSDavid du Colombier.CW BR . 10967dd7cddfSDavid du ColombierIndirect branches use 10977dd7cddfSDavid du Colombier.CW "(CTR)" 10987dd7cddfSDavid du Colombieror 10997dd7cddfSDavid du Colombier.CW "(LR)" 11007dd7cddfSDavid du Colombieras target. 11017dd7cddfSDavid du Colombier.PP 11027dd7cddfSDavid du ColombierLoad or store operations are replaced by 11037dd7cddfSDavid du Colombier.CW MOV 11047dd7cddfSDavid du Colombiervariants in the usual way: 11057dd7cddfSDavid du Colombier.CW MOVW 11067dd7cddfSDavid du Colombier(move word), 11077dd7cddfSDavid du Colombier.CW MOVH 11087dd7cddfSDavid du Colombier(move halfword with sign extension), and 11097dd7cddfSDavid du Colombier.CW MOVB 11107dd7cddfSDavid du Colombier(move byte with sign extension, a pseudo-instruction), 11117dd7cddfSDavid du Colombierwith unsigned variants 11127dd7cddfSDavid du Colombier.CW MOVHZ 11137dd7cddfSDavid du Colombierand 11147dd7cddfSDavid du Colombier.CW MOVBZ , 11157dd7cddfSDavid du Colombierand byte-reversing 11167dd7cddfSDavid du Colombier.CW MOVWBR 11177dd7cddfSDavid du Colombierand 11187dd7cddfSDavid du Colombier.CW MOVHBR . 11197dd7cddfSDavid du Colombier`Load or store with update' versions are 11207dd7cddfSDavid du Colombier.CW MOVWU , 11217dd7cddfSDavid du Colombier.CW MOVHU , 11227dd7cddfSDavid du Colombierand 11237dd7cddfSDavid du Colombier.CW MOVBZU . 11247dd7cddfSDavid du ColombierLoad or store multiple is 11257dd7cddfSDavid du Colombier.CW MOVMW . 11267dd7cddfSDavid du ColombierThe exceptions are the string instructions, which are 11277dd7cddfSDavid du Colombier.CW LSW 11287dd7cddfSDavid du Colombierand 11297dd7cddfSDavid du Colombier.CW STSW , 11307dd7cddfSDavid du Colombierand the reservation instructions 11317dd7cddfSDavid du Colombier.CW lwarx 11327dd7cddfSDavid du Colombierand 11337dd7cddfSDavid du Colombier.CW stwcx. , 11347dd7cddfSDavid du Colombierwhich are 11357dd7cddfSDavid du Colombier.CW LWAR 11367dd7cddfSDavid du Colombierand 11377dd7cddfSDavid du Colombier.CW STWCCC , 11387dd7cddfSDavid du Colombierall with operands in the usual data-flow order. 11397dd7cddfSDavid du ColombierFloating-point load or store instructions are 11407dd7cddfSDavid du Colombier.CW FMOVD , 11417dd7cddfSDavid du Colombier.CW FMOVDU , 11427dd7cddfSDavid du Colombier.CW FMOVS , 11437dd7cddfSDavid du Colombierand 11447dd7cddfSDavid du Colombier.CW FMOVSU . 11457dd7cddfSDavid du ColombierThe register to register move instructions 11467dd7cddfSDavid du Colombier.CW fmr 11477dd7cddfSDavid du Colombierand 11487dd7cddfSDavid du Colombier.CW fmr. 11497dd7cddfSDavid du Colombierare written 11507dd7cddfSDavid du Colombier.CW FMOVD 11517dd7cddfSDavid du Colombierand 11527dd7cddfSDavid du Colombier.CW FMOVDCC . 11537dd7cddfSDavid du Colombier.PP 11547dd7cddfSDavid du ColombierThe assembler knows the commonly used special purpose registers: 11557dd7cddfSDavid du Colombier.CW CR , 11567dd7cddfSDavid du Colombier.CW CTR , 11577dd7cddfSDavid du Colombier.CW DEC , 11587dd7cddfSDavid du Colombier.CW LR , 11597dd7cddfSDavid du Colombier.CW MSR , 11607dd7cddfSDavid du Colombierand 11617dd7cddfSDavid du Colombier.CW XER . 11627dd7cddfSDavid du ColombierThe rest, which are often architecture-dependent, are referenced as 11637dd7cddfSDavid du Colombier.CW SPR(n) . 11647dd7cddfSDavid du ColombierThe segment registers of the 60x series are similarly 11657dd7cddfSDavid du Colombier.CW SEG(n) , 11667dd7cddfSDavid du Colombierbut 11677dd7cddfSDavid du Colombier.I n 11687dd7cddfSDavid du Colombiercan also be a register name, as in 11697dd7cddfSDavid du Colombier.CW SEG(R3) . 11707dd7cddfSDavid du ColombierMoves between special purpose registers and general purpose ones, 11717dd7cddfSDavid du Colombierwhen allowed by the architecture, 11727dd7cddfSDavid du Colombierare written as 11737dd7cddfSDavid du Colombier.CW MOVW , 11747dd7cddfSDavid du Colombierreplacing 11757dd7cddfSDavid du Colombier.CW mfcr , 11767dd7cddfSDavid du Colombier.CW mtcr , 11777dd7cddfSDavid du Colombier.CW mfmsr , 11787dd7cddfSDavid du Colombier.CW mtmsr , 11797dd7cddfSDavid du Colombier.CW mtspr , 11807dd7cddfSDavid du Colombier.CW mfspr , 11817dd7cddfSDavid du Colombier.CW mftb , 11827dd7cddfSDavid du Colombierand many others. 11837dd7cddfSDavid du Colombier.PP 11847dd7cddfSDavid du ColombierThe fields of the condition register 11857dd7cddfSDavid du Colombier.CW CR 11867dd7cddfSDavid du Colombierare referenced as 11877dd7cddfSDavid du Colombier.CW CR(0) 11887dd7cddfSDavid du Colombierthrough 11897dd7cddfSDavid du Colombier.CW CR(7) . 11907dd7cddfSDavid du ColombierThey are used by the 11917dd7cddfSDavid du Colombier.CW MOVFL 11927dd7cddfSDavid du Colombier(move field) pseudo-instruction, 11937dd7cddfSDavid du Colombierwhich produces 11947dd7cddfSDavid du Colombier.CW mcrf 11957dd7cddfSDavid du Colombieror 11967dd7cddfSDavid du Colombier.CW mtcrf . 11977dd7cddfSDavid du ColombierFor example: 11987dd7cddfSDavid du Colombier.P1 11997dd7cddfSDavid du Colombier MOVFL CR(3), CR(0) 12007dd7cddfSDavid du Colombier MOVFL R3, CR(1) 12017dd7cddfSDavid du Colombier MOVFL R3, $7, CR 12027dd7cddfSDavid du Colombier.P2 12037dd7cddfSDavid du ColombierThey are also accepted in 12047dd7cddfSDavid du Colombierthe conditional branch instruction, for example 12057dd7cddfSDavid du Colombier.P1 12067dd7cddfSDavid du Colombier BEQ CR(7), label 12077dd7cddfSDavid du Colombier.P2 12087dd7cddfSDavid du ColombierFields of the 12097dd7cddfSDavid du Colombier.CW FPSCR 12107dd7cddfSDavid du Colombierare accessed using 12117dd7cddfSDavid du Colombier.CW MOVFL 12127dd7cddfSDavid du Colombierin a similar way: 12137dd7cddfSDavid du Colombier.P1 12147dd7cddfSDavid du Colombier MOVFL FPSCR, F0 12157dd7cddfSDavid du Colombier MOVFL F0, FPSCR 12167dd7cddfSDavid du Colombier MOVFL F0, $7, FPSCR 12177dd7cddfSDavid du Colombier MOVFL $0, FPSCR(3) 12187dd7cddfSDavid du Colombier.P2 12197dd7cddfSDavid du Colombierproducing 12207dd7cddfSDavid du Colombier.CW mffs , 12217dd7cddfSDavid du Colombier.CW mtfsf 12227dd7cddfSDavid du Colombieror 12237dd7cddfSDavid du Colombier.CW mtfsfi , 12247dd7cddfSDavid du Colombieras appropriate. 12257dd7cddfSDavid du Colombier.SH 12267dd7cddfSDavid du ColombierARM 12277dd7cddfSDavid du Colombier.PP 12287dd7cddfSDavid du ColombierThe assembler provides access to 12297dd7cddfSDavid du Colombier.CW R0 12307dd7cddfSDavid du Colombierthrough 12317dd7cddfSDavid du Colombier.CW R14 12327dd7cddfSDavid du Colombierand the 12337dd7cddfSDavid du Colombier.CW PC . 12347dd7cddfSDavid du ColombierThe stack pointer is 12357dd7cddfSDavid du Colombier.CW R13 , 12367dd7cddfSDavid du Colombierthe link register is 12377dd7cddfSDavid du Colombier.CW R14 , 12387dd7cddfSDavid du Colombierand the static base register is 12397dd7cddfSDavid du Colombier.CW R12 . 12407dd7cddfSDavid du Colombier.CW R0 12417dd7cddfSDavid du Colombieris the return register and also the register holding 12427dd7cddfSDavid du Colombierthe first argument to a subroutine. 1243f722162aSDavid du ColombierThe external registers in Plan 9's C are allocated from 1244f722162aSDavid du Colombier.CW R10 1245f722162aSDavid du Colombierdown. 1246f722162aSDavid du Colombier.CW R11 1247f722162aSDavid du Colombieris used by the loader as a temporary register. 12487dd7cddfSDavid du ColombierThe assembler supports the 12497dd7cddfSDavid du Colombier.CW CPSR 12507dd7cddfSDavid du Colombierand 12517dd7cddfSDavid du Colombier.CW SPSR 12527dd7cddfSDavid du Colombierregisters. 12537dd7cddfSDavid du ColombierIt also knows about coprocessor registers 12547dd7cddfSDavid du Colombier.CW C0 12557dd7cddfSDavid du Colombierthrough 12567dd7cddfSDavid du Colombier.CW C15 . 12577dd7cddfSDavid du ColombierFloating registers are 12587dd7cddfSDavid du Colombier.CW F0 12597dd7cddfSDavid du Colombierthrough 12607dd7cddfSDavid du Colombier.CW F7 , 12617dd7cddfSDavid du Colombier.CW FPSR 12627dd7cddfSDavid du Colombierand 12637dd7cddfSDavid du Colombier.CW FPCR . 12647dd7cddfSDavid du Colombier.PP 12657dd7cddfSDavid du ColombierAs with the other architectures, loads and stores are called 12667dd7cddfSDavid du Colombier.CW MOV , 12677dd7cddfSDavid du Colombiere.g. 12687dd7cddfSDavid du Colombier.CW MOVW 12697dd7cddfSDavid du Colombierfor load word or store word, and 12707dd7cddfSDavid du Colombier.CW MOVM 12717dd7cddfSDavid du Colombierfor 12727dd7cddfSDavid du Colombierload or store multiple, 12737dd7cddfSDavid du Colombierdepending on the operands. 12747dd7cddfSDavid du Colombier.PP 12757dd7cddfSDavid du ColombierAddressing modes are supported by suffixes to the instructions: 12767dd7cddfSDavid du Colombier.CW .IA 12777dd7cddfSDavid du Colombier(increment after), 12787dd7cddfSDavid du Colombier.CW .IB 12797dd7cddfSDavid du Colombier(increment before), 12807dd7cddfSDavid du Colombier.CW .DA 12817dd7cddfSDavid du Colombier(decrement after), and 12827dd7cddfSDavid du Colombier.CW .DB 12837dd7cddfSDavid du Colombier(decrement before). 12847dd7cddfSDavid du ColombierThese can only be used with the 12857dd7cddfSDavid du Colombier.CW MOV 1286219b2ee8SDavid du Colombierinstructions. 12877dd7cddfSDavid du ColombierThe move multiple instruction, 12887dd7cddfSDavid du Colombier.CW MOVM , 12897dd7cddfSDavid du Colombierdefines a range of registers using brackets, e.g. 12907dd7cddfSDavid du Colombier.CW [R0-R12] . 12917dd7cddfSDavid du ColombierThe special 12927dd7cddfSDavid du Colombier.CW MOVM 12937dd7cddfSDavid du Colombieraddressing mode bits 12947dd7cddfSDavid du Colombier.CW W , 12957dd7cddfSDavid du Colombier.CW U , 12967dd7cddfSDavid du Colombierand 12977dd7cddfSDavid du Colombier.CW P 12987dd7cddfSDavid du Colombierare written in the same manner, for example, 12997dd7cddfSDavid du Colombier.CW MOVM.DB.W . 13007dd7cddfSDavid du ColombierA 13017dd7cddfSDavid du Colombier.CW .S 13027dd7cddfSDavid du Colombiersuffix allows a 13037dd7cddfSDavid du Colombier.CW MOVM 13047dd7cddfSDavid du Colombierinstruction to access user 13057dd7cddfSDavid du Colombier.CW R13 13067dd7cddfSDavid du Colombierand 13077dd7cddfSDavid du Colombier.CW R14 13087dd7cddfSDavid du Colombierwhen in another processor mode. 13097dd7cddfSDavid du ColombierShifts and rotates in addressing modes are supported by binary operators 13107dd7cddfSDavid du Colombier.CW << 13117dd7cddfSDavid du Colombier(logical left shift), 13127dd7cddfSDavid du Colombier.CW >> 13137dd7cddfSDavid du Colombier(logical right shift), 13147dd7cddfSDavid du Colombier.CW -> 13157dd7cddfSDavid du Colombier(arithmetic right shift), and 13167dd7cddfSDavid du Colombier.CW @> 13177dd7cddfSDavid du Colombier(rotate right); for example 13187dd7cddfSDavid du Colombier.CW "R7>>R2" or 13197dd7cddfSDavid du Colombier.CW "R2@>2" . 13207dd7cddfSDavid du ColombierThe assembler does not support indexing by a shifted expression; 13217dd7cddfSDavid du Colombieronly names can be doubly indexed. 1322219b2ee8SDavid du Colombier.PP 13237dd7cddfSDavid du ColombierAny instruction can be followed by a suffix that makes the instruction conditional: 13247dd7cddfSDavid du Colombier.CW .EQ , 13257dd7cddfSDavid du Colombier.CW .NE , 13267dd7cddfSDavid du Colombierand so on, as in the ARM manual, with synonyms 13277dd7cddfSDavid du Colombier.CW .HS 13287dd7cddfSDavid du Colombier(for 13297dd7cddfSDavid du Colombier.CW .CS ) 13307dd7cddfSDavid du Colombierand 13317dd7cddfSDavid du Colombier.CW .LO 13327dd7cddfSDavid du Colombier(for 1333fab2bff7SDavid du Colombier.CW .CC ), 1334fab2bff7SDavid du Colombierfor example 13357dd7cddfSDavid du Colombier.CW ADD.NE . 13367dd7cddfSDavid du ColombierArithmetic 13377dd7cddfSDavid du Colombierand logical instructions 13387dd7cddfSDavid du Colombiercan have a 13397dd7cddfSDavid du Colombier.CW .S 13407dd7cddfSDavid du Colombiersuffix, as ARM allows, to set condition codes. 1341219b2ee8SDavid du Colombier.PP 13427dd7cddfSDavid du ColombierThe syntax of the 13437dd7cddfSDavid du Colombier.CW MCR 13447dd7cddfSDavid du Colombierand 13457dd7cddfSDavid du Colombier.CW MRC 13467dd7cddfSDavid du Colombiercoprocessor instructions is largely as in the manual, with the usual adjustments. 13477dd7cddfSDavid du ColombierThe assembler directly supports only the ARM floating-point coprocessor 13487dd7cddfSDavid du Colombieroperations used by the compiler: 13497dd7cddfSDavid du Colombier.CW CMP , 13507dd7cddfSDavid du Colombier.CW ADD , 13517dd7cddfSDavid du Colombier.CW SUB , 13527dd7cddfSDavid du Colombier.CW MUL , 13537dd7cddfSDavid du Colombierand 13547dd7cddfSDavid du Colombier.CW DIV , 13557dd7cddfSDavid du Colombierall with 13567dd7cddfSDavid du Colombier.CW F 13577dd7cddfSDavid du Colombieror 13587dd7cddfSDavid du Colombier.CW D 13597dd7cddfSDavid du Colombiersuffix selecting single or double precision. 13607dd7cddfSDavid du ColombierFloating-point load or store become 13617dd7cddfSDavid du Colombier.CW MOVF 13627dd7cddfSDavid du Colombierand 13637dd7cddfSDavid du Colombier.CW MOVD . 13647dd7cddfSDavid du ColombierConversion instructions are also specified by moves: 13657dd7cddfSDavid du Colombier.CW MOVWD , 13667dd7cddfSDavid du Colombier.CW MOVWF , 13677dd7cddfSDavid du Colombier.CW MOVDW , 13687dd7cddfSDavid du Colombier.CW MOVWD , 13697dd7cddfSDavid du Colombier.CW MOVFD , 13707dd7cddfSDavid du Colombierand 13717dd7cddfSDavid du Colombier.CW MOVDF . 1372