Allow mfspr, mtspr with a register number.
authorGeorge Koehler <xkernigh@netscape.net>
Wed, 7 Dec 2016 22:28:00 +0000 (17:28 -0500)
committerGeorge Koehler <xkernigh@netscape.net>
Wed, 7 Dec 2016 22:28:00 +0000 (17:28 -0500)
PowerPC has a few hundred special-purpose registers.  The assembler
had only accepted the names "xer", "lr", "ctr".  Most programs use
only those three SPRs.  If I add more names, they would almost never
get used, and they might conflict with labels.

I want to use "mfspr r3, 0x3f0" and "mtspr 0x3f0, r3" in
plat/qemu/boot.s to access register hid0 from supervisor mode.

mach/powerpc/as/mach2.c
mach/powerpc/as/mach4.c

index 96d6690..480c5fa 100644 (file)
@@ -88,4 +88,4 @@
 
 %type <y_word> c
 %type <y_word> e16 u8 u7 u6 u5 u4 u2 u1
-%type <y_word> nb ds bda bdl lia lil
+%type <y_word> nb ds bda bdl lia lil spr_num
index 3f79ca8..e1fb3fd 100644 (file)
@@ -34,7 +34,7 @@ operation
     | OP_RT_RA_RB_C        c GPR ',' GPR ',' GPR      { emit4($1 | $2 | ($3<<21) | ($5<<16) | ($7<<11)); }
        | OP_RT_RA_SI          GPR ',' GPR ',' e16        { emit4($1 | ($2<<21) | ($4<<16) | $6); }
        | OP_RT_RA_SI_addic    c GPR ',' GPR ',' e16      { emit4($1 | ($2<<26) | ($3<<21) | ($5<<16) | $7); }
-       | OP_RT_SPR            GPR ',' SPR                { emit4($1 | ($2<<21) | ($4<<11)); }
+       | OP_RT_SPR            GPR ',' spr_num            { emit4($1 | ($2<<21) | ($4<<11)); }
        | OP_RS_FXM            u7 ',' GPR                 { emit4($1 | ($4<<21) | ($2<<12)); }
        | OP_RS_RA_C           c GPR ',' GPR              { emit4($1 | $2 | ($5<<21) | ($3<<16)); }
        | OP_RS_RA_D           GPR ',' e16 '(' GPR ')'    { emit4($1 | ($2<<21) | ($6<<16) | $4); }
@@ -53,7 +53,7 @@ operation
        | OP_RS_RA_SH_ME6_SH_C  c GPR ',' GPR ',' u6 ',' u6 { emit4($1 | $2 | ($5<<21) | ($3<<16) | (($7&0x1F)<<11) | ($9<<6) | (($7&0x20)>>4)); }
        | OP_RS_RA_SH5_C       c GPR ',' GPR ',' u5       { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11)); }
        | OP_RS_RA_SH6_C       c GPR ',' GPR ',' u6       { emit4($1 | $2 | ($5<<21) | ($3<<16) | (($7&0x1F)<<11) | (($7&0x20)>>4)); }
-       | OP_RS_SPR            SPR ',' GPR                { emit4($1 | ($4<<21) | ($2<<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         { emit4($1 | ($2<<21) | ($4<<16) | $6); }
        | OP_LEV               u7                         { emit4($1 | ($2<<5)); }
@@ -237,4 +237,14 @@ lia
                $$ = target & 0x03FFFFFD;
        }
        ;
-       
+
+spr_num
+       : SPR { $$ = $1; }
+       | absexp
+       {
+               if (($1 < 0) || ($1 > 0x3ff))
+                       serror("spr number out of range");
+               /* mfspr, mtspr swap the low and high 5 bits */
+               $$ = ($1 >> 5) | (($1 & 0x1f) << 5);
+       }
+       ;