From b8c921ca70c17a51b74e39d11974e130c32ed409 Mon Sep 17 00:00:00 2001 From: George Koehler Date: Wed, 7 Dec 2016 17:28:00 -0500 Subject: [PATCH] Allow mfspr, mtspr with a register number. 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 | 2 +- mach/powerpc/as/mach4.c | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/mach/powerpc/as/mach2.c b/mach/powerpc/as/mach2.c index 96d6690df..480c5faa3 100644 --- a/mach/powerpc/as/mach2.c +++ b/mach/powerpc/as/mach2.c @@ -88,4 +88,4 @@ %type c %type e16 u8 u7 u6 u5 u4 u2 u1 -%type nb ds bda bdl lia lil +%type nb ds bda bdl lia lil spr_num diff --git a/mach/powerpc/as/mach4.c b/mach/powerpc/as/mach4.c index 3f79ca86c..e1fb3fdf0 100644 --- a/mach/powerpc/as/mach4.c +++ b/mach/powerpc/as/mach4.c @@ -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); + } + ;