diff --git a/mach/powerpc/as/mach2.c b/mach/powerpc/as/mach2.c index 4065334e6..e8e61ea0c 100644 --- a/mach/powerpc/as/mach2.c +++ b/mach/powerpc/as/mach2.c @@ -47,11 +47,15 @@ %token OP_FRT_FRB_C %token OP_FRT_RA_D %token OP_FRT_RA_RB +%token OP_L %token OP_LEV %token OP_LIA %token OP_LIL %token OP_LI32 +%token OP_RA_RB +%token OP_RA_RB_TH %token OP_RA_RS_C +%token OP_RA_RS_RA_C %token OP_RA_RS_RB_C %token OP_RA_RS_RB_MB5_ME5_C %token OP_RA_RS_RB_MB6_C @@ -61,14 +65,14 @@ %token OP_RA_RS_SH6_MB6_C %token OP_RA_RS_UI %token OP_RA_RS_UI_CC +%token OP_RS %token OP_RS_FXM %token OP_RS_RA %token OP_RS_RA_D %token OP_RS_RA_DS %token OP_RS_RA_NB %token OP_RS_RA_RB -%token OP_RS_RA_RB_C -%token OP_RS_RA_RA_C +%token OP_RS_RA_RB_CC %token OP_RS_RB %token OP_RS_SPR %token OP_RS_SR @@ -104,4 +108,5 @@ %type c %type e16 negate16 u8 u7 u6 u5 u4 u2 u1 -%type opt_bh cr_opt nb ds bda bdl lia lil spr_num +%type opt_bh cr_opt nb ds bda bdl lia lil +%type spr_num tbr_num opt_tbr diff --git a/mach/powerpc/as/mach3.c b/mach/powerpc/as/mach3.c index 91b088a6a..99507087d 100644 --- a/mach/powerpc/as/mach3.c +++ b/mach/powerpc/as/mach3.c @@ -103,6 +103,10 @@ 0, OP_HA, 0, "ha16", 0, OP_LO, 0, "lo16", +/* The next page numbers are from PowerPC User Instruction Set + * Architecture, Book I, Version 2.01. + */ + /* Branch processor instructions (page 20) */ 0, OP_LIL, 18<<26 | 0<<1 | 0<<0, "b", @@ -128,7 +132,7 @@ 0, OP_BT_BA_BB, 19<<26 | 417<<1, "crorc", 0, OP_BF_BFA, 19<<26 | 0<<1, "mcrf", -/* extended mnemonics for bc, bcctr, bclr */ +/* extended mnemonics for bc, bcctr, bclr (page 144) */ 0, OP_BH, 19<<26 | 20<<21 | 528<<1 | 0<<0, "bctr", 0, OP_BH, 19<<26 | 20<<21 | 528<<1 | 1<<0, "bctrl", 0, OP_BDL, 16<<26 | 16<<21 | 0<<1 | 0<<0, "bdnz", @@ -186,7 +190,7 @@ 0, OP_BI_BH, 19<<26 | 12<<21 | 16<<1 | 0<<0, "btlr", 0, OP_BI_BH, 19<<26 | 12<<21 | 16<<1 | 1<<0, "btlrl", -/* extended m with condition in BI */ +/* extended m with condition in BI (page 146) */ 0, OP_BICR_BDL, 16<<26 | 12<<21 | 2<<16 | 0<<1 | 0<<0, "beq", 0, OP_BICR_BDA, 16<<26 | 12<<21 | 2<<16 | 1<<1 | 0<<0, "beqa", 0, OP_BICR_BH, 19<<26 | 12<<21 | 2<<16 | 528<<1 | 0<<0, "beqctr", @@ -284,7 +288,7 @@ 0, OP_BICR_BH, 19<<26 | 12<<21 | 3<<16 | 16<<1 | 0<<0, "bunlr", 0, OP_BICR_BH, 19<<26 | 12<<21 | 3<<16 | 16<<1 | 1<<0, "bunlrl", -/* extended m for cr logic */ +/* extended m for cr logic (page 147) */ 0, OP_BT_BT_BT, 19<<26 | 289<<1, "crset", 0, OP_BT_BT_BT, 19<<26 | 193<<1, "crclr", 0, OP_BT_BA_BA, 19<<26 | 449<<1, "crmove", @@ -377,12 +381,12 @@ 0, OP_RT_RA_C, 31<<26 | 0<<10 | 104<<1, "neg", 0, OP_RT_RA_C, 31<<26 | 1<<10 | 104<<1, "nego", -/* extended m for addition */ +/* extended m for addition (pages 153, 154) */ 0, OP_RT_RA_D, 14<<26, "la", 0, OP_RT_SI, 14<<26 | 0<<16, "li", 0, OP_RT_SI, 15<<26 | 0<<16, "lis", -/* extended m for subtraction */ +/* extended m for subtraction (pages 147, 148) */ 0, OP_RT_RB_RA_C, 31<<26 | 0<<10 | 40<<1, "sub", 0, OP_RT_RB_RA_C, 31<<26 | 1<<10 | 40<<1, "subo", 0, OP_RT_RB_RA_C, 31<<26 | 0<<10 | 8<<1, "subc", @@ -418,7 +422,7 @@ 0, OP_BF_L_RA_UI, 10<<26, "cmpli", 0, OP_BF_L_RA_RB, 31<<26 | 32<<1, "cmpl", -/* extended m for comparison */ +/* extended m for comparison (page 149) */ 0, OP_BF_RA_SI, 11<<26 | 1<<21, "cmpdi", 0, OP_BF_RA_RB, 31<<26 | 1<<21 | 0<<1, "cmpd", 0, OP_BF_RA_UI, 10<<26 | 1<<21, "cmpldi", @@ -434,7 +438,7 @@ 0, OP_TO_RA_RB, 31<<26 | 68<<1, "td", 0, OP_TO_RA_RB, 31<<26 | 4<<1, "tw", -/* extended m for traps */ +/* extended m for traps (page 150) */ 0, OP_TOX_RA_RB, 31<<26 | 4<<21 | 68<<1, "tdeq", 0, OP_TOX_RA_SI, 2<<26 | 4<<21, "tdeqi", 0, OP_TOX_RA_RB, 31<<26 | 12<<21 | 68<<1, "tdge", @@ -518,11 +522,10 @@ 0, OP_RA_RS_C, 31<<26 | 58<<1, "cntlzd", 0, OP_RA_RS_C, 31<<26 | 26<<1, "cntlzw", -/* extended m using logic */ -0, OP_RS_RA_RA_C, 31<<26 | 444<<1, "mr", +/* extended m using logic (pages 153, 154) */ +0, OP_RA_RS_RA_C, 31<<26 | 444<<1, "mr", 0, OP, 24<<26, "nop", -0, OP_RS_RA_RA_C, 31<<26 | 124<<1, "not", -0, OP, 26<<26, "xnop", +0, OP_RA_RS_RA_C, 31<<26 | 124<<1, "not", /* page 69 */ 0, OP_RA_RS_SH6_MB6_C, 30<<26 | 0<<2, "rldicl", @@ -535,7 +538,7 @@ 0, OP_RA_RS_SH6_MB6_C, 30<<26 | 3<<2, "rldimi", 0, OP_RA_RS_SH5_MB5_ME5_C, 20<<26, "rlwimi", -/* extended m for doubleword rotation */ +/* extended m for doubleword rotation (page 151) */ 0, OP_clrlsldi, 30<<26 | 2<<2, "clrlsldi", 0, OP_clrldi, 30<<26 | 0<<2, "clrldi", 0, OP_clrrdi, 30<<26 | 1<<2, "clrrdi", @@ -548,7 +551,7 @@ 0, OP_sldi, 30<<26 | 1<<2, "sldi", 0, OP_srdi, 30<<26 | 0<<2, "srdi", -/* extended m for word rotation */ +/* extended m for word rotation (page 152) */ 0, OP_clrlslwi, 21<<26, "clrlslwi", 0, OP_clrlwi, 21<<26, "clrlwi", 0, OP_clrrwi, 21<<26, "clrrwi", @@ -573,21 +576,25 @@ 0, OP_RA_RS_RB_C, 31<<26 | 792<<1, "sraw", /* page 78 */ -0, OP_RS_SPR, 31<<26 | 467<<1, "mtspr", -0, OP_RT_SPR, 31<<26 | 339<<1, "mfspr", -0, OP_RS_FXM, 31<<26 | 0<<21 | 144<<1, "mtcrf", -0, OP_RT, 31<<26 | 0<<21 | 19<<1, "mfcr", +0, OP_RS_SPR, 31<<26 | 467<<1, "mtspr", +0, OP_RT_SPR, 31<<26 | 339<<1, "mfspr", +0, OP_RS_FXM, 31<<26 | 0<<20 | 144<<1, "mtcrf", +0, OP_RT, 31<<26 | 0<<20 | 19<<1, "mfcr", -/* extended m for special purpose registers */ +/* extended m for special purpose registers (page 153) */ 0, OP_RT, 31<<26 | 9<<16 | 0<<11 | 339<<1, "mfctr", 0, OP_RT, 31<<26 | 8<<16 | 0<<11 | 339<<1, "mflr", 0, OP_RT, 31<<26 | 1<<16 | 0<<11 | 339<<1, "mfxer", -0, OP_RT, 31<<26 | 9<<16 | 0<<11 | 467<<1, "mtctr", -0, OP_RT, 31<<26 | 8<<16 | 0<<11 | 467<<1, "mtlr", -0, OP_RT, 31<<26 | 1<<16 | 0<<11 | 467<<1, "mtxer", +0, OP_RS, 31<<26 | 9<<16 | 0<<11 | 467<<1, "mtctr", +0, OP_RS, 31<<26 | 8<<16 | 0<<11 | 467<<1, "mtlr", +0, OP_RS, 31<<26 | 1<<16 | 0<<11 | 467<<1, "mtxer", + +/* extended m for condition register (page 154) */ +0, OP_RS, 31<<26 | 0<<20 | 255<<12 | 144<<1, "mtcr", /* Floating point instructions (page 83) */ +/* page 98 */ 0, OP_FRT_RA_D, 48<<26, "lfs", 0, OP_FRT_RA_RB, 31<<26 | 535<<1, "lfsx", 0, OP_FRT_RA_D, 49<<26, "lfsu", @@ -606,6 +613,7 @@ 0, OP_FRS_RA_RB, 31<<26 | 759<<1, "stfdux", 0, OP_FRS_RA_RB, 31<<26 | 983<<1, "stfiwx", +/* page 104 */ 0, OP_FRT_FRB_C, 63<<26 | 72<<1, "fmr", 0, OP_FRT_FRB_C, 63<<26 | 40<<1, "fneg", 0, OP_FRT_FRB_C, 63<<26 | 264<<1, "fabs", @@ -629,6 +637,7 @@ 0, OP_FRT_FRA_FRC_FRB_C, 63<<26 | 30<<1, "fnmsub", 0, OP_FRT_FRA_FRC_FRB_C, 59<<26 | 30<<1, "fnmsubs", +/* page 109 */ 0, OP_FRT_FRB_C, 63<<26 | 12<<1, "frsp", 0, OP_FRT_FRB_C, 63<<26 | 814<<1, "fctid", 0, OP_FRT_FRB_C, 63<<26 | 815<<1, "fctidz", @@ -652,4 +661,31 @@ 0, OP_FRT_FRB_C, 63<<26 | 26<<1, "frsqrte", 0, OP_FRT_FRA_FRC_FRB_C, 63<<26 | 23<<1, "fsel", -/* page 98 */ +/* Storage control instructions (Book II, page 15) */ + +/* Book II, page 17 */ +0, OP_RA_RB, 31<<26 | 982<<1, "icbi", +0, OP_RA_RB_TH /* page 35 */, 31<<26 | 278<<1, "dcbt", +0, OP_RA_RB, 31<<26 | 246<<1, "dcbtst", +0, OP_RA_RB, 31<<26 | 1014<<1, "dcbz", +0, OP_RA_RB, 31<<26 | 54<<1, "dcbst", +0, OP_RA_RB, 31<<26 | 86<<1, "dcbf", +0, OP, 19<<26 | 150<<1, "isync", +0, OP_RT_RA_RB, 31<<26 | 20<<1, "lwarx", +0, OP_RT_RA_RB, 31<<26 | 84<<1, "ldarx", +0, OP_RS_RA_RB_CC, 31<<26 | 150<<1 | 1<<0, "stwcx", +0, OP_RS_RA_RB_CC, 31<<26 | 150<<1 | 1<<0, "stdcx", +0, OP_L, 31<<26 | 598<<1, "sync", +0, OP, 31<<26 | 1<<21 | 598<<1, "lwsync", +0, OP, 31<<26 | 2<<21 | 598<<1, "ptesync", +0, OP, 31<<26 | 854<<1, "eieio", + +/* Time base (Book II, page 30) */ + +0, OP_RT_TBR, 31<<26 | 371<<1, "mftb", +0, OP_RT, 31<<26 | 8<<11 | 13<<16 | 371<<1, "mftbu", + +/* External control (Book II, page 33) */ + +0, OP_RT_RA_RB, 31<<26 | 310<<1, "eciwx", +0, OP_RS_RA_RB, 31<<26 | 438<<1, "ecowx", diff --git a/mach/powerpc/as/mach4.c b/mach/powerpc/as/mach4.c index 8a0cca9de..b344ba8ce 100644 --- a/mach/powerpc/as/mach4.c +++ b/mach/powerpc/as/mach4.c @@ -42,7 +42,23 @@ operation | OP_FRT_RA_D FPR ',' e16 '(' GPR ')' { emit_hl($1 | ($2<<21) | ($6<<16) | $4); } | OP_FRT_RA_RB FPR ',' GPR ',' GPR { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); } | OP_FRT_C c FPR { emit4($1 | $2 | ($3<<21)); } - | OP_RA_RS_C c GPR ',' GPR { emit4($1 | $2 | ($5<<21) | ($3<<16)); } + | OP_L { emit4($1); } + | OP_L u2 { emit4($1 | ($2<<21)); } + | OP_LEV { emit4($1); } + | OP_LEV u7 { emit4($1 | ($2<<5)); } + | OP_RA_RB GPR ',' GPR + { emit4($1 | ($2<<16) | ($4<<11)); } + | OP_RA_RB_TH GPR ',' GPR opt_bh + { emit4($1 | $5 | ($2<<16) | ($4<<11)); } + /* + * For instructions with "mnemonic RS, RA, ..." + * OP_RA_RS_... swaps RS and RA to (RA<<21) || (RS<<16) + * OP_RS_RA_... keeps RS and RA as (RS<<21) || (RA<<16) + */ + | OP_RA_RS_C c GPR ',' GPR + { emit4($1 | $2 | ($5<<21) | ($3<<16)); } + | OP_RA_RS_RA_C c GPR ',' GPR + { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($5<<11)); } | OP_RA_RS_RB_C c GPR ',' GPR ',' GPR { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11)); } | OP_RA_RS_RB_MB5_ME5_C c GPR ',' GPR ',' GPR ',' u5 ',' u5 @@ -75,20 +91,19 @@ operation | OP_RT_RB_RA_C c GPR ',' GPR ',' GPR { emit4($1 | $2 | ($3<<21) | ($7<<16) | ($5<<11)); } | OP_RT_SI GPR ',' e16 { emit_hl($1 | ($2<<21) | $4); } | OP_RT_SPR GPR ',' spr_num { emit4($1 | ($2<<21) | ($4<<11)); } + | OP_RT_TBR GPR opt_tbr { emit4($1 | ($2<<21) | ($3<<11)); } + | OP_RS GPR { emit4($1 | ($2<<21)); } | OP_RS_FXM u7 ',' GPR { emit4($1 | ($4<<21) | ($2<<12)); } | OP_RS_RA_D GPR ',' e16 '(' GPR ')' { emit_hl($1 | ($2<<21) | ($6<<16) | $4); } | OP_RS_RA_DS GPR ',' ds '(' GPR ')' { emit_hl($1 | ($2<<21) | ($6<<16) | $4); } | OP_RS_RA_NB GPR ',' GPR ',' nb { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); } | OP_RS_RA_RB GPR ',' GPR ',' GPR { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); } - | OP_RS_RA_RB_C c GPR ',' GPR ',' GPR { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11)); } - | OP_RS_RA_RA_C c GPR ',' GPR { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($5<<11)); } + | OP_RS_RA_RB_CC C GPR ',' GPR ',' GPR { emit4($1 | ($3<<21) | ($5<<16) | ($7<<11)); } | OP_RS_SPR spr_num ',' GPR { emit4($1 | ($4<<21) | ($2<<11)); } | OP_TO_RA_RB u5 ',' GPR ',' GPR { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); } | OP_TO_RA_SI u5 ',' GPR ',' e16 { emit_hl($1 | ($2<<21) | ($4<<16) | $6); } | OP_TOX_RA_RB GPR ',' GPR { emit4($1 | ($2<<16) | ($4<<11)); } | OP_TOX_RA_SI GPR ',' e16 { emit_hl($1 | ($2<<16) | $4); } - | OP_LEV { emit4($1); } - | OP_LEV u7 { emit4($1 | ($2<<5)); } | OP_LIA lia { emit4($1 | $2); } | OP_LIL lil { emit4($1 | $2); } | OP_LI32 li32 /* emitted in subrule */ @@ -298,7 +313,7 @@ u2 } ; -/* Optional comma, branch hint. */ +/* Optional comma, branch hint (or touch hint). */ opt_bh : /* nothing */ { $$ = 0; } | ',' u2 { $$ = ($2<<11); } @@ -409,13 +424,28 @@ lia } ; +/* + * Instructions "mfspr", "mtspr", and "mftb" encode the 10-bit special + * purpose register (spr) or time base register (tbr) by swapping the + * low 5 bits with the high 5 bits. The value from an SPR token has + * already been swapped. + */ + spr_num - : SPR { $$ = $1; } - | absexp + : SPR { $$ = $1; } + | tbr_num { $$ = $1; } + ; + +opt_tbr + : /* nothing */ { $$ = 8 | (12<<5); } + | ',' tbr_num { $$ = $2; } + ; + +tbr_num + : absexp { if (($1 < 0) || ($1 > 0x3ff)) - serror("spr number out of range"); - /* mfspr, mtspr swap the low and high 5 bits */ + serror("10-bit unsigned value out of range"); $$ = ($1 >> 5) | (($1 & 0x1f) << 5); } ; diff --git a/man/powerpc_as.6 b/man/powerpc_as.6 index 8198d6bce..f6bb90818 100644 --- a/man/powerpc_as.6 +++ b/man/powerpc_as.6 @@ -1,33 +1,136 @@ -.TH POWERPC_AS 1 +.TH POWERPC_AS 1 2018-03-07 .ad .SH NAME powerpc_as \- assembler for PowerPC - .SH SYNOPSIS as [options] argument ... - .SH DESCRIPTION This assembler is made with the general framework described in \fIuni_ass\fP(6). - +.PP +It can assemble the instructions from Book I and Book II of PowerPC +version 2.01. +This includes the branch, integer, and floating point instructions +from Book I; and the cache, synchronization, and time base +instructions from Book II. +.PP +There is no support for other instructions, such as supervisor-mode +instructions or vector instructions. +There is some support for 64-bit integer instructions, but the +assembler only has 32-bit symbols. .SH SYNTAX -Most 32-bit integer and floating point instructions are supported, but not many -short form instructions. Instructions which take 16-bit operands can additionally -use the following special functions: - -.IP hi16[value], ha16[value] -Returns the high half of the value of the expression; if the value is not absolute, -also generates the appropriate fixup. Use of either of these \fImust\fR be followed, -in the next instruction, by the corresponding use of \fBlo16[]\fR. Use \fBhi16[]\fR -if the low half is going to interpret its payload as an unsigned value, and -\fBha16[]\fR if it will be interpreted as a signed value (so that the high half can -be adjusted to match). - -.IP lo16[] -Returns the low half of the value of the expression. No fixup is generated. Use of -\fBlo16[]\fR must come in the instruction immediately after a use of \fBhi16[]\fR or -\fBha16[]\fR. - +.SS general purpose registers +There are 32 GPRs from \fBr0\fP to \fBr31\fP. +In this assembler, \fBsp\fP is an alias for \fBr1\fP, and \fBfp\fP is +an alias for \fBr2\fP, because \fIack\fP uses r1 as the stack pointer +and r2 as the frame pointer. +Other compilers don't use r2 as the frame pointer. +.PP +GPR syntax requires a register name, not a number. +For example, \(oqaddi\ r5,\ r4,\ 1\(cq works, but +\(oqaddi\ 5,\ 4,\ 1\(cq is a syntax error. +.PP +Certain instructions ignore the contents of \fBr0\fP and use zero. +This happens when using r0 as the second operand of \fIaddi\fP or +\fIaddis\fP, or when addressing \(oqexpr(r0)\(cq or +\(oqr0,\ gpr\(cq. +The syntax is still the name r0, not the number 0. +.SS floating point registers +There are 32 FPRs from \fBf0\fP to \fBf31\fP. +Each FPR has 64 bits and can hold a single-precision or +double-precision number. +FPR syntax requires a register name, not a number. +.SS special purpose registers +The three named SPRs are \fBctr\fP (count register), \fBlr\fP (link +register), and \fBxer\fP (exception register). +\(oqmfspr\(cq and \(oqmtspr\(cq allow these names or a number. +.SS condition register +There is a 32-bit condition register, where bit 0 is most significant, +and bit 31 is least significant. +This gets split into 8 registers of 4 bits each, from \fBcr0\fP (with +bits 0 to 3) to \fBcr7\fP (with bits 28 to 31). +Some instructions use the names cr0 to cr7, others use a bit numbered +0 to 31, and others use all 32 bits. +.SS addressing modes +\(oqexpr(gpr)\(cq addresses \fIexpr\fP + the contents of \fIgpr\fP, +except that \(oqexpr(r0)\(cq addresses \fIexpr\fP\ +\ 0. +A few instructions, like \(oqstwu\(cq, also update \fIgpr\fP by +setting it to the address. +.PP +\(oqgprA,\ gprB\(cq in certain instructions addresses the contents of +\fIgprA\fP + the contents of \fIgprB\fP, except that \(oqr0,\ gprB\(cq +addresses 0\ +\ the contents of \fIgprB\fP. +.SS 16-bit operands +Some instructions have a 16-bit operand. +This can be a bare \fIexpr\fP (which must fit signed or unsigned +16 bits), or it can be one of these special functions: +.IP "hi16[expr], ha16[expr]" +Returns the high half of the 32-bit value of the expression. +If the low half is negative (from 0x8000 to 0xffff), +then \fBha16[]\fP adjusts the high half by adding 1. +Use \fBhi16[]\fP if the instruction with \fBlo16[]\fP is going to +interpret its operand as an unsigned value, or \fBha16[]\fP if it will +interpret it as signed. +.IP +If \fIexpr\fP is not absolute, then the assembler must generate a +fixup for the linker. +The fixup only works if the instruction is +\(oqaddis gpr, r0, hx16[expr]\(cq or \(oqlis gpr, hx16[expr]\(cq. +.IP lo16[expr] +Returns the low half of the 32-bit value of the expression. +.SS short forms +Some instructions have short forms using extended mnemonics (or +simplified mnemonics) like \fIli\fP, \fIsrwi\fP, and many others. +.IP "li r6, 789" +is short for: addi r6, r0, 789 +.IP "srwi r3, r4, 2" +is short for: rlwinm r3, r4, 30, 2, 31 +.PP +This assembler doesn't support extended mnemonics with branch +prediction, such as \fIblt+\fP or \fIbne-\fP. +It always parses \(oq+\(cq and \(oq-\(cq as operators, +never as part of a mnemonic. +.SH EXAMPLES +There are two ways to load r3 with _symbol\ =\ 0x1234abcd. +One way is +.PP +.nf + lis r3, hi16[_symbol] + ori r3, r3, lo16[_symbol] ! r3 = 0x12340000 | 0x0000abcd +.fi +.PP +The other way is +.PP +.nf + lis r3, ha16[_symbol] + addi r3, r3, lo16[_symbol] ! r3 = 0x12350000 + 0xffffabcd +.fi +.PP +The next code adds 1 to a global variable. +.PP +.nf + lis r3, ha16[_var] + lwz r4, lo16[_var](r3) + addi r4, r4, 1 + stw r4, lo16[_var](r3) +.fi .SH "SEE ALSO" uni_ass(6), ack(1) +.PP +Freescale Semiconductor, \fIProgramming Environments Manual for 32-Bit +Implementations of the PowerPC Architecture\fP, Rev. 3, September 2005. +.PP +IBM, \fIPowerPC User Instruction Set Architecture, Book I\fP, Version +2.01, September 2003. +.PP +IBM, \fIPowerPC Virtual Environment Architecture, Book II\fP, Version +2.01, December 2003. +.SH CAVEATS +Beware that not every processor can run every instruction. +The 32-bit processors can't run 64-bit instructions like \fIlwa\fP, +\fIstd\fP, and \fIfctid\fP. +The PowerPC 601 can't run \fIstfiwx\fP, nor \fIfres\fP, \fIfrsqrte\fP, +\fIfsel\fP. +Many models, like the PowerPC G4, can't run \fIfsqrt\fP nor +\fIfsqrts\fP.