diff --git a/mach/powerpc/as/mach0.c b/mach/powerpc/as/mach0.c index 325c08910..3246828fc 100644 --- a/mach/powerpc/as/mach0.c +++ b/mach/powerpc/as/mach0.c @@ -31,3 +31,9 @@ typedef uint32_t quad; #define VALWIDTH 8 #define FIXUPFLAGS (RELBR | RELWR) + +/* 6-bit mb (mask begin) or me (mask end) field */ +#define MB6(v) (((v) & 0x1F)<<6 | ((v) & 0x20)>>0) + +/* 6-bit sh (shift) field */ +#define SH6(v) (((v) & 0x1F)<<11 | ((v) & 0x20)>>4) diff --git a/mach/powerpc/as/mach2.c b/mach/powerpc/as/mach2.c index 3ecaf10cf..555b92c38 100644 --- a/mach/powerpc/as/mach2.c +++ b/mach/powerpc/as/mach2.c @@ -8,20 +8,35 @@ %token FPR %token CR %token C +%token OP_HI OP_HA OP_LO %token OP +%token OP_BDA +%token OP_BDL %token OP_BF %token OP_BF_BFA %token OP_BF_FRA_FRB %token OP_BF_L_RA_RB %token OP_BF_L_RA_SI %token OP_BF_L_RA_UI +%token OP_BF_RA_RB +%token OP_BF_RA_SI +%token OP_BF_RA_UI %token OP_BF_U_C +%token OP_BH +%token OP_BI_BDA +%token OP_BI_BDL +%token OP_BI_BH +%token OP_BICR_BDA +%token OP_BICR_BDL +%token OP_BICR_BH %token OP_BO_BI_BDA %token OP_BO_BI_BDL %token OP_BO_BI_BH %token OP_BT_C +%token OP_BT_BA_BA %token OP_BT_BA_BB +%token OP_BT_BT_BT %token OP_FLM_FRB_C %token OP_FRS_RA_D %token OP_FRS_RA_RB @@ -32,16 +47,18 @@ %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_L_RB -%token OP_RA_RB -%token OP_RB -%token OP_RS +%token OP_LI32 +%token OP_RA_RS_RB_C +%token OP_RA_RS_RB_MB5_ME5_C +%token OP_RA_RS_RB_MB6_C +%token OP_RA_RS_SH5_C +%token OP_RA_RS_SH5_MB5_ME5_C +%token OP_RA_RS_SH6_C +%token OP_RA_RS_SH6_MB6_C %token OP_RS_FXM -%token OP_RS_L %token OP_RS_RA %token OP_RS_RA_C %token OP_RS_RA_D @@ -50,14 +67,6 @@ %token OP_RS_RA_RB %token OP_RS_RA_RB_C %token OP_RS_RA_RA_C -%token OP_RS_RA_RB_MB5_ME5_C -%token OP_RS_RA_RB_MB6_C -%token OP_RS_RA_RB_ME6_C -%token OP_RS_RA_SH_MB5_ME5_C -%token OP_RS_RA_SH_MB6_SH_C -%token OP_RS_RA_SH_ME6_SH_C -%token OP_RS_RA_SH5_C -%token OP_RS_RA_SH6_C %token OP_RS_RA_UI %token OP_RS_RA_UI_CC %token OP_RS_RB @@ -73,22 +82,26 @@ %token OP_RT_RA_RB_C %token OP_RT_RA_SI %token OP_RT_RA_SI_addic +%token OP_RT_RA_SI_subi +%token OP_RT_RA_SI_subic %token OP_RT_RB +%token OP_RT_RB_RA_C +%token OP_RT_SI %token OP_RT_SPR %token OP_RT_SR %token OP_RT_TBR %token OP_TH_RA_RB %token OP_TO_RA_RB %token OP_TO_RA_SI - -%token OP_LA -%token OP_LI32 - -%token OP_POWERPC_FIXUP -%token OP_HI OP_HA OP_LO +%token OP_TOX_RA_RB +%token OP_TOX_RA_SI +%token OP_clrlsldi OP_clrldi OP_clrrdi OP_extldi OP_extrdi +%token OP_insrdi OP_rotrdi OP_sldi OP_srdi +%token OP_clrlslwi OP_clrlwi OP_clrrwi OP_extlwi OP_extrwi +%token OP_inslwi OP_insrwi OP_rotlwi OP_rotrwi OP_slwi OP_srwi /* Other token types */ %type c -%type e16 u8 u7 u6 u5 u4 u2 u1 -%type nb ds bda bdl lia lil spr_num +%type e16 negate16 u8 u7 u6 u5 u4 u2 u1 +%type opt_bh cr_opt nb ds bda bdl lia lil spr_num diff --git a/mach/powerpc/as/mach3.c b/mach/powerpc/as/mach3.c index 724ba7312..16c1e6ae0 100644 --- a/mach/powerpc/as/mach3.c +++ b/mach/powerpc/as/mach3.c @@ -99,9 +99,6 @@ /* Special instructions */ 0, OP_LI32, 0, "li32", -0, OP_LA, 0, "la", -0, OP_LA, 0, "li", -0, OP_RS_RA_RA_C, 31<<26 | 444<<1, "mr", 0, OP_HI, 0, "hi16", 0, OP_HA, 0, "ha16", 0, OP_LO, 0, "lo16", @@ -126,11 +123,173 @@ 0, OP_BT_BA_BB, 19<<26 | 193<<1, "crxor", 0, OP_BT_BA_BB, 19<<26 | 225<<1, "crnand", 0, OP_BT_BA_BB, 19<<26 | 33<<1, "crnor", -0, OP_BT_BA_BB, 19<<26 | 289<<1, "crneqv", +0, OP_BT_BA_BB, 19<<26 | 289<<1, "creqv", 0, OP_BT_BA_BB, 19<<26 | 129<<1, "crandc", 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 */ +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", +0, OP_BDA, 16<<26 | 16<<21 | 1<<1 | 0<<0, "bdnza", +0, OP_BH, 19<<26 | 16<<21 | 16<<1 | 0<<0, "bdnzlr", +0, OP_BDL, 16<<26 | 16<<21 | 0<<1 | 1<<0, "bdnzl", +0, OP_BDA, 16<<26 | 16<<21 | 1<<1 | 1<<0, "bdnzla", +0, OP_BH, 19<<26 | 16<<21 | 16<<1 | 1<<0, "bdnzlrl", +0, OP_BI_BDL, 16<<26 | 0<<21 | 0<<1 | 0<<0, "bdnzf", +0, OP_BI_BDA, 16<<26 | 0<<21 | 1<<1 | 0<<0, "bdnzfa", +0, OP_BI_BH, 19<<26 | 0<<21 | 16<<1 | 0<<0, "bdnzflr", +0, OP_BI_BDL, 16<<26 | 0<<21 | 0<<1 | 1<<0, "bdnzfl", +0, OP_BI_BDA, 16<<26 | 0<<21 | 1<<1 | 1<<0, "bdnzfla", +0, OP_BI_BH, 19<<26 | 0<<21 | 16<<1 | 1<<0, "bdnzflrl", +0, OP_BI_BDL, 16<<26 | 8<<21 | 0<<1 | 0<<0, "bdnzt", +0, OP_BI_BDA, 16<<26 | 8<<21 | 1<<1 | 0<<0, "bdnzta", +0, OP_BI_BH, 19<<26 | 8<<21 | 16<<1 | 0<<0, "bdnztlr", +0, OP_BI_BDL, 16<<26 | 8<<21 | 0<<1 | 1<<0, "bdnztl", +0, OP_BI_BDA, 16<<26 | 8<<21 | 1<<1 | 1<<0, "bdnztla", +0, OP_BI_BH, 19<<26 | 8<<21 | 16<<1 | 1<<0, "bdnztlrl", +0, OP_BDL, 16<<26 | 18<<21 | 0<<1 | 0<<0, "bdz", +0, OP_BDA, 16<<26 | 18<<21 | 1<<1 | 0<<0, "bdza", +0, OP_BH, 19<<26 | 18<<21 | 16<<1 | 0<<0, "bdzlr", +0, OP_BDL, 16<<26 | 18<<21 | 0<<1 | 1<<0, "bdzl", +0, OP_BDA, 16<<26 | 18<<21 | 1<<1 | 1<<0, "bdzla", +0, OP_BH, 19<<26 | 18<<21 | 16<<1 | 1<<0, "bdzlrl", +0, OP_BI_BDL, 16<<26 | 2<<21 | 0<<1 | 0<<0, "bdzf", +0, OP_BI_BDA, 16<<26 | 2<<21 | 1<<1 | 0<<0, "bdzfa", +0, OP_BI_BH, 19<<26 | 2<<21 | 16<<1 | 0<<0, "bdzflr", +0, OP_BI_BDL, 16<<26 | 2<<21 | 0<<1 | 1<<0, "bdzfl", +0, OP_BI_BDA, 16<<26 | 2<<21 | 1<<1 | 1<<0, "bdzfla", +0, OP_BI_BH, 19<<26 | 2<<21 | 16<<1 | 1<<0, "bdzflrl", +0, OP_BI_BDL, 16<<26 | 10<<21 | 0<<1 | 0<<0, "bdzt", +0, OP_BI_BDA, 16<<26 | 10<<21 | 1<<1 | 0<<0, "bdzta", +0, OP_BI_BH, 19<<26 | 10<<21 | 16<<1 | 0<<0, "bdztlr", +0, OP_BI_BDL, 16<<26 | 10<<21 | 0<<1 | 1<<0, "bdztl", +0, OP_BI_BDA, 16<<26 | 10<<21 | 1<<1 | 1<<0, "bdztla", +0, OP_BI_BH, 19<<26 | 10<<21 | 16<<1 | 1<<0, "bdztlrl", +0, OP_BI_BDL, 16<<26 | 4<<21 | 0<<1 | 0<<0, "bf", +0, OP_BI_BDA, 16<<26 | 4<<21 | 1<<1 | 0<<0, "bfa", +0, OP_BI_BH, 19<<26 | 4<<21 | 528<<1 | 0<<0, "bfctr", +0, OP_BI_BH, 19<<26 | 4<<21 | 528<<1 | 1<<0, "bfctrl", +0, OP_BI_BDL, 16<<26 | 4<<21 | 0<<1 | 1<<0, "bfl", +0, OP_BI_BDA, 16<<26 | 4<<21 | 0<<1 | 1<<0, "bfla", +0, OP_BI_BH, 19<<26 | 4<<21 | 16<<1 | 0<<0, "bflr", +0, OP_BI_BH, 19<<26 | 4<<21 | 16<<1 | 1<<0, "bflrl", +0, OP_BH, 19<<26 | 20<<21 | 16<<1 | 0<<0, "blr", +0, OP_BH, 19<<26 | 20<<21 | 16<<1 | 1<<0, "blrl", +0, OP_BI_BDL, 16<<26 | 12<<21 | 0<<1 | 0<<0, "bt", +0, OP_BI_BDA, 16<<26 | 12<<21 | 1<<1 | 0<<0, "bta", +0, OP_BI_BH, 19<<26 | 12<<21 | 528<<1 | 0<<0, "btctr", +0, OP_BI_BH, 19<<26 | 12<<21 | 528<<1 | 1<<0, "btctrl", +0, OP_BI_BDL, 16<<26 | 12<<21 | 0<<1 | 1<<0, "btl", +0, OP_BI_BDA, 16<<26 | 12<<21 | 0<<1 | 1<<0, "btla", +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 */ +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", +0, OP_BICR_BH, 19<<26 | 12<<21 | 2<<16 | 528<<1 | 1<<0, "beqctrl", +0, OP_BICR_BDL, 16<<26 | 12<<21 | 2<<16 | 0<<1 | 1<<0, "beql", +0, OP_BICR_BDA, 16<<26 | 12<<21 | 2<<16 | 1<<1 | 1<<0, "beqla", +0, OP_BICR_BH, 19<<26 | 12<<21 | 2<<16 | 16<<1 | 0<<0, "beqlr", +0, OP_BICR_BH, 19<<26 | 12<<21 | 2<<16 | 16<<1 | 1<<0, "beqlrl", +0, OP_BICR_BDL, 16<<26 | 4<<21 | 0<<16 | 0<<1 | 0<<0, "bge", +0, OP_BICR_BDA, 16<<26 | 4<<21 | 0<<16 | 1<<1 | 0<<0, "bgea", +0, OP_BICR_BH, 19<<26 | 4<<21 | 0<<16 | 528<<1 | 0<<0, "bgectr", +0, OP_BICR_BH, 19<<26 | 4<<21 | 0<<16 | 528<<1 | 1<<0, "bgectrl", +0, OP_BICR_BDL, 16<<26 | 4<<21 | 0<<16 | 0<<1 | 1<<0, "bgel", +0, OP_BICR_BDA, 16<<26 | 4<<21 | 0<<16 | 1<<1 | 1<<0, "bgela", +0, OP_BICR_BH, 19<<26 | 4<<21 | 0<<16 | 16<<1 | 0<<0, "bgelr", +0, OP_BICR_BH, 19<<26 | 4<<21 | 0<<16 | 16<<1 | 1<<0, "bgelrl", +0, OP_BICR_BDL, 16<<26 | 12<<21 | 1<<16 | 0<<1 | 0<<0, "bgt", +0, OP_BICR_BDA, 16<<26 | 12<<21 | 1<<16 | 1<<1 | 0<<0, "bgta", +0, OP_BICR_BH, 19<<26 | 12<<21 | 1<<16 | 528<<1 | 0<<0, "bgtctr", +0, OP_BICR_BH, 19<<26 | 12<<21 | 1<<16 | 528<<1 | 1<<0, "bgtctrl", +0, OP_BICR_BDL, 16<<26 | 12<<21 | 1<<16 | 0<<1 | 1<<0, "bgtl", +0, OP_BICR_BDA, 16<<26 | 12<<21 | 1<<16 | 1<<1 | 1<<0, "bgtla", +0, OP_BICR_BH, 19<<26 | 12<<21 | 1<<16 | 16<<1 | 0<<0, "bgtlr", +0, OP_BICR_BH, 19<<26 | 12<<21 | 1<<16 | 16<<1 | 1<<0, "bgtlrl", +0, OP_BICR_BDL, 16<<26 | 4<<21 | 1<<16 | 0<<1 | 0<<0, "ble", +0, OP_BICR_BDA, 16<<26 | 4<<21 | 1<<16 | 1<<1 | 0<<0, "blea", +0, OP_BICR_BH, 19<<26 | 4<<21 | 1<<16 | 528<<1 | 0<<0, "blectr", +0, OP_BICR_BH, 19<<26 | 4<<21 | 1<<16 | 528<<1 | 1<<0, "blectrl", +0, OP_BICR_BDL, 16<<26 | 4<<21 | 1<<16 | 0<<1 | 1<<0, "blel", +0, OP_BICR_BDA, 16<<26 | 4<<21 | 1<<16 | 1<<1 | 1<<0, "blela", +0, OP_BICR_BH, 19<<26 | 4<<21 | 1<<16 | 16<<1 | 0<<0, "blelr", +0, OP_BICR_BH, 19<<26 | 4<<21 | 1<<16 | 16<<1 | 1<<0, "blelrl", +0, OP_BICR_BDL, 16<<26 | 12<<21 | 0<<16 | 0<<1 | 0<<0, "blt", +0, OP_BICR_BDA, 16<<26 | 12<<21 | 0<<16 | 1<<1 | 0<<0, "blta", +0, OP_BICR_BH, 19<<26 | 12<<21 | 0<<16 | 528<<1 | 0<<0, "bltctr", +0, OP_BICR_BH, 19<<26 | 12<<21 | 0<<16 | 528<<1 | 1<<0, "bltctrl", +0, OP_BICR_BDL, 16<<26 | 12<<21 | 0<<16 | 0<<1 | 1<<0, "bltl", +0, OP_BICR_BDA, 16<<26 | 12<<21 | 0<<16 | 1<<1 | 1<<0, "bltla", +0, OP_BICR_BH, 19<<26 | 12<<21 | 0<<16 | 16<<1 | 0<<0, "bltlr", +0, OP_BICR_BH, 19<<26 | 12<<21 | 0<<16 | 16<<1 | 1<<0, "bltlrl", +0, OP_BICR_BDL, 16<<26 | 4<<21 | 2<<16 | 0<<1 | 0<<0, "bne", +0, OP_BICR_BDA, 16<<26 | 4<<21 | 2<<16 | 1<<1 | 0<<0, "bnea", +0, OP_BICR_BH, 19<<26 | 4<<21 | 2<<16 | 528<<1 | 0<<0, "bnectr", +0, OP_BICR_BH, 19<<26 | 4<<21 | 2<<16 | 528<<1 | 1<<0, "bnectrl", +0, OP_BICR_BDL, 16<<26 | 4<<21 | 2<<16 | 0<<1 | 1<<0, "bnel", +0, OP_BICR_BDA, 16<<26 | 4<<21 | 2<<16 | 1<<1 | 1<<0, "bnela", +0, OP_BICR_BH, 19<<26 | 4<<21 | 2<<16 | 16<<1 | 0<<0, "bnelr", +0, OP_BICR_BH, 19<<26 | 4<<21 | 2<<16 | 16<<1 | 1<<0, "bnelrl", +0, OP_BICR_BDL, 16<<26 | 4<<21 | 1<<16 | 0<<1 | 0<<0, "bng", +0, OP_BICR_BDA, 16<<26 | 4<<21 | 1<<16 | 1<<1 | 0<<0, "bnga", +0, OP_BICR_BH, 19<<26 | 4<<21 | 1<<16 | 528<<1 | 0<<0, "bngctr", +0, OP_BICR_BH, 19<<26 | 4<<21 | 1<<16 | 528<<1 | 1<<0, "bngctrl", +0, OP_BICR_BDL, 16<<26 | 4<<21 | 1<<16 | 0<<1 | 1<<0, "bngl", +0, OP_BICR_BDA, 16<<26 | 4<<21 | 1<<16 | 1<<1 | 1<<0, "bngla", +0, OP_BICR_BH, 19<<26 | 4<<21 | 1<<16 | 16<<1 | 0<<0, "bnglr", +0, OP_BICR_BH, 19<<26 | 4<<21 | 1<<16 | 16<<1 | 1<<0, "bnglrl", +0, OP_BICR_BDL, 16<<26 | 4<<21 | 0<<16 | 0<<1 | 0<<0, "bnl", +0, OP_BICR_BDA, 16<<26 | 4<<21 | 0<<16 | 1<<1 | 0<<0, "bnla", +0, OP_BICR_BH, 19<<26 | 4<<21 | 0<<16 | 528<<1 | 0<<0, "bnlctr", +0, OP_BICR_BH, 19<<26 | 4<<21 | 0<<16 | 528<<1 | 1<<0, "bnlctrl", +0, OP_BICR_BDL, 16<<26 | 4<<21 | 0<<16 | 0<<1 | 1<<0, "bnll", +0, OP_BICR_BDA, 16<<26 | 4<<21 | 0<<16 | 1<<1 | 1<<0, "bnlla", +0, OP_BICR_BH, 19<<26 | 4<<21 | 0<<16 | 16<<1 | 0<<0, "bnllr", +0, OP_BICR_BH, 19<<26 | 4<<21 | 0<<16 | 16<<1 | 1<<0, "bnllrl", +0, OP_BICR_BDL, 16<<26 | 4<<21 | 3<<16 | 0<<1 | 0<<0, "bns", +0, OP_BICR_BDA, 16<<26 | 4<<21 | 3<<16 | 1<<1 | 0<<0, "bnsa", +0, OP_BICR_BH, 19<<26 | 4<<21 | 3<<16 | 528<<1 | 0<<0, "bnsctr", +0, OP_BICR_BH, 19<<26 | 4<<21 | 3<<16 | 528<<1 | 1<<0, "bnsctrl", +0, OP_BICR_BDL, 16<<26 | 4<<21 | 3<<16 | 0<<1 | 1<<0, "bnsl", +0, OP_BICR_BDA, 16<<26 | 4<<21 | 3<<16 | 1<<1 | 1<<0, "bnsla", +0, OP_BICR_BH, 19<<26 | 4<<21 | 3<<16 | 16<<1 | 0<<0, "bnslr", +0, OP_BICR_BH, 19<<26 | 4<<21 | 3<<16 | 16<<1 | 1<<0, "bnslrl", +0, OP_BICR_BDL, 16<<26 | 4<<21 | 3<<16 | 0<<1 | 0<<0, "bnu", +0, OP_BICR_BDA, 16<<26 | 4<<21 | 3<<16 | 1<<1 | 0<<0, "bnua", +0, OP_BICR_BH, 19<<26 | 4<<21 | 3<<16 | 528<<1 | 0<<0, "bnuctr", +0, OP_BICR_BH, 19<<26 | 4<<21 | 3<<16 | 528<<1 | 1<<0, "bnuctrl", +0, OP_BICR_BDL, 16<<26 | 4<<21 | 3<<16 | 0<<1 | 1<<0, "bnul", +0, OP_BICR_BDA, 16<<26 | 4<<21 | 3<<16 | 1<<1 | 1<<0, "bnula", +0, OP_BICR_BH, 19<<26 | 4<<21 | 3<<16 | 16<<1 | 0<<0, "bnulr", +0, OP_BICR_BH, 19<<26 | 4<<21 | 3<<16 | 16<<1 | 1<<0, "bnulrl", +0, OP_BICR_BDL, 16<<26 | 12<<21 | 3<<16 | 0<<1 | 0<<0, "bso", +0, OP_BICR_BDA, 16<<26 | 12<<21 | 3<<16 | 1<<1 | 0<<0, "bsoa", +0, OP_BICR_BH, 19<<26 | 12<<21 | 3<<16 | 528<<1 | 0<<0, "bsoctr", +0, OP_BICR_BH, 19<<26 | 12<<21 | 3<<16 | 528<<1 | 1<<0, "bsoctrl", +0, OP_BICR_BDL, 16<<26 | 12<<21 | 3<<16 | 0<<1 | 1<<0, "bsol", +0, OP_BICR_BDA, 16<<26 | 12<<21 | 3<<16 | 1<<1 | 1<<0, "bsola", +0, OP_BICR_BH, 19<<26 | 12<<21 | 3<<16 | 16<<1 | 0<<0, "bsolr", +0, OP_BICR_BH, 19<<26 | 12<<21 | 3<<16 | 16<<1 | 1<<0, "bsolrl", +0, OP_BICR_BDL, 16<<26 | 12<<21 | 3<<16 | 0<<1 | 0<<0, "bun", +0, OP_BICR_BDA, 16<<26 | 12<<21 | 3<<16 | 1<<1 | 0<<0, "buna", +0, OP_BICR_BH, 19<<26 | 12<<21 | 3<<16 | 528<<1 | 0<<0, "bunctr", +0, OP_BICR_BH, 19<<26 | 12<<21 | 3<<16 | 528<<1 | 1<<0, "bunctrl", +0, OP_BICR_BDL, 16<<26 | 12<<21 | 3<<16 | 0<<1 | 1<<0, "bunl", +0, OP_BICR_BDA, 16<<26 | 12<<21 | 3<<16 | 1<<1 | 1<<0, "bunla", +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 */ +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", +0, OP_BT_BA_BA, 19<<26 | 33<<1, "crnot", + /* Fixed point instructions (page 29) */ 0, OP_RT_RA_D, 34<<26, "lbz", @@ -199,6 +358,10 @@ 0, OP_RT_RA_RB_C, 31<<26 | 1<<10 | 40<<1, "subfo", 0, OP_RT_RA_SI_addic, 12<<26, "addic", /* special case C */ 0, OP_RT_RA_SI, 8<<26, "subfic", +0, OP_RT_RA_RB_C, 31<<26 | 0<<10 | 10<<1, "addc", +0, OP_RT_RA_RB_C, 31<<26 | 1<<10 | 10<<1, "addco", +0, OP_RT_RA_RB_C, 31<<26 | 0<<10 | 8<<1, "subfc", +0, OP_RT_RA_RB_C, 31<<26 | 1<<10 | 8<<1, "subfco", 0, OP_RT_RA_RB_C, 31<<26 | 0<<10 | 138<<1, "adde", 0, OP_RT_RA_RB_C, 31<<26 | 1<<10 | 138<<1, "addeo", 0, OP_RT_RA_RB_C, 31<<26 | 0<<10 | 136<<1, "subfe", @@ -214,6 +377,20 @@ 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 */ +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 */ +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", +0, OP_RT_RB_RA_C, 31<<26 | 0<<10 | 8<<1, "subco", +0, OP_RT_RA_SI_subi, 14<<26, "subi", +0, OP_RT_RA_SI_subi, 15<<26, "subis", +0, OP_RT_RA_SI_subic, 12<<26, "subic", + /* page 54 */ 0, OP_RT_RA_SI, 7<<26, "mulli", 0, OP_RT_RA_RB_C, 31<<26 | 0<<10 | 233<<1, "mulld", @@ -241,12 +418,85 @@ 0, OP_BF_L_RA_UI, 10<<26, "cmpli", 0, OP_BF_L_RA_RB, 31<<26 | 32<<1, "cmpl", +/* extended m for comparison */ +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", +0, OP_BF_RA_RB, 31<<26 | 1<<21 | 32<<1, "cmpld", +0, OP_BF_RA_SI, 11<<26 | 0<<21, "cmpwi", +0, OP_BF_RA_RB, 31<<26 | 0<<21 | 0<<1, "cmpw", +0, OP_BF_RA_UI, 10<<26 | 0<<21, "cmplwi", +0, OP_BF_RA_RB, 31<<26 | 0<<21 | 32<<1, "cmplw", + /* page 60 */ 0, OP_TO_RA_SI, 2<<26, "tdi", 0, OP_TO_RA_SI, 3<<26, "twi", 0, OP_TO_RA_RB, 31<<26 | 68<<1, "td", 0, OP_TO_RA_RB, 31<<26 | 4<<1, "tw", +/* extended m for traps */ +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", +0, OP_TOX_RA_SI, 2<<26 | 12<<21, "tdgei", +0, OP_TOX_RA_RB, 31<<26 | 8<<21 | 68<<1, "tdgt", +0, OP_TOX_RA_SI, 2<<26 | 8<<21, "tdgti", +0, OP_TOX_RA_RB, 31<<26 | 20<<21 | 68<<1, "tdle", +0, OP_TOX_RA_SI, 2<<26 | 20<<21, "tdlei", +0, OP_TOX_RA_RB, 31<<26 | 5<<21 | 68<<1, "tdlge", +0, OP_TOX_RA_SI, 2<<26 | 5<<21, "tdlgei", +0, OP_TOX_RA_RB, 31<<26 | 1<<21 | 68<<1, "tdlgt", +0, OP_TOX_RA_SI, 2<<26 | 1<<21, "tdlgti", +0, OP_TOX_RA_RB, 31<<26 | 6<<21 | 68<<1, "tdlle", +0, OP_TOX_RA_SI, 2<<26 | 6<<21, "tdllei", +0, OP_TOX_RA_RB, 31<<26 | 2<<21 | 68<<1, "tdllt", +0, OP_TOX_RA_SI, 2<<26 | 2<<21, "tdllti", +0, OP_TOX_RA_RB, 31<<26 | 6<<21 | 68<<1, "tdlng", +0, OP_TOX_RA_SI, 2<<26 | 6<<21, "tdlngi", +0, OP_TOX_RA_RB, 31<<26 | 5<<21 | 68<<1, "tdlnl", +0, OP_TOX_RA_SI, 2<<26 | 5<<21, "tdlnli", +0, OP_TOX_RA_RB, 31<<26 | 16<<21 | 68<<1, "tdlt", +0, OP_TOX_RA_SI, 2<<26 | 16<<21, "tdlti", +0, OP_TOX_RA_RB, 31<<26 | 24<<21 | 68<<1, "tdne", +0, OP_TOX_RA_SI, 2<<26 | 24<<21, "tdnei", +0, OP_TOX_RA_RB, 31<<26 | 20<<21 | 68<<1, "tdng", +0, OP_TOX_RA_SI, 2<<26 | 20<<21, "tdngi", +0, OP_TOX_RA_RB, 31<<26 | 12<<21 | 68<<1, "tdnl", +0, OP_TOX_RA_SI, 2<<26 | 12<<21, "tdnli", +0, OP_TOX_RA_RB, 31<<26 | 31<<21 | 68<<1, "tdu", +0, OP_TOX_RA_SI, 2<<26 | 31<<21, "tdui", +0, OP, 31<<26 | 31<<21 | 4<<1, "trap", +0, OP_TOX_RA_RB, 31<<26 | 4<<21 | 4<<1, "tweq", +0, OP_TOX_RA_SI, 3<<26 | 4<<21, "tweqi", +0, OP_TOX_RA_RB, 31<<26 | 12<<21 | 4<<1, "twge", +0, OP_TOX_RA_SI, 3<<26 | 12<<21, "twgei", +0, OP_TOX_RA_RB, 31<<26 | 8<<21 | 4<<1, "twgt", +0, OP_TOX_RA_SI, 3<<26 | 8<<21, "twgti", +0, OP_TOX_RA_RB, 31<<26 | 20<<21 | 4<<1, "twle", +0, OP_TOX_RA_SI, 3<<26 | 20<<21, "twlei", +0, OP_TOX_RA_RB, 31<<26 | 5<<21 | 4<<1, "twlge", +0, OP_TOX_RA_SI, 3<<26 | 5<<21, "twlgei", +0, OP_TOX_RA_RB, 31<<26 | 1<<21 | 4<<1, "twlgt", +0, OP_TOX_RA_SI, 3<<26 | 1<<21, "twlgti", +0, OP_TOX_RA_RB, 31<<26 | 6<<21 | 4<<1, "twlle", +0, OP_TOX_RA_SI, 3<<26 | 6<<21, "twllei", +0, OP_TOX_RA_RB, 31<<26 | 2<<21 | 4<<1, "twllt", +0, OP_TOX_RA_SI, 3<<26 | 2<<21, "twllti", +0, OP_TOX_RA_RB, 31<<26 | 6<<21 | 4<<1, "twlng", +0, OP_TOX_RA_SI, 3<<26 | 6<<21, "twlngi", +0, OP_TOX_RA_RB, 31<<26 | 5<<21 | 4<<1, "twlnl", +0, OP_TOX_RA_SI, 3<<26 | 5<<21, "twlnli", +0, OP_TOX_RA_RB, 31<<26 | 16<<21 | 4<<1, "twlt", +0, OP_TOX_RA_SI, 3<<26 | 16<<21, "twlti", +0, OP_TOX_RA_RB, 31<<26 | 24<<21 | 4<<1, "twne", +0, OP_TOX_RA_SI, 3<<26 | 24<<21, "twnei", +0, OP_TOX_RA_RB, 31<<26 | 20<<21 | 4<<1, "twng", +0, OP_TOX_RA_SI, 3<<26 | 20<<21, "twngi", +0, OP_TOX_RA_RB, 31<<26 | 12<<21 | 4<<1, "twnl", +0, OP_TOX_RA_SI, 3<<26 | 12<<21, "twnli", +0, OP_TOX_RA_RB, 31<<26 | 31<<21 | 4<<1, "twu", +0, OP_TOX_RA_SI, 3<<26 | 31<<21, "twui", + /* page 62 */ 0, OP_RS_RA_UI_CC, 28<<26, "andi", /* C compulsory */ 0, OP_RS_RA_UI_CC, 29<<26, "andis", /* C compulsory */ @@ -268,26 +518,59 @@ 0, OP_RS_RA_C, 31<<26 | 58<<1, "cntlzd", 0, OP_RS_RA_C, 31<<26 | 26<<1, "cntlzw", +/* extended m using logic */ +0, OP_RS_RA_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", + /* page 69 */ -0, OP_RS_RA_SH_MB6_SH_C, 30<<26 | 0<<2, "rldicl", -0, OP_RS_RA_SH_ME6_SH_C, 30<<26 | 1<<2, "rldicr", -0, OP_RS_RA_SH_MB6_SH_C, 30<<26 | 2<<2, "rldic", -0, OP_RS_RA_SH_MB5_ME5_C, 21<<26, "rlwinm", -0, OP_RS_RA_RB_MB6_C, 30<<26 | 8<<1, "rldcl", -0, OP_RS_RA_RB_ME6_C, 30<<26 | 9<<1, "rldcr", -0, OP_RS_RA_RB_MB5_ME5_C, 23<<26, "rlwnm", -0, OP_RS_RA_SH_MB6_SH_C, 30<<26 | 3<<2, "rldimi", -0, OP_RS_RA_SH_MB5_ME5_C, 20<<26, "rlwimi", +0, OP_RA_RS_SH6_MB6_C, 30<<26 | 0<<2, "rldicl", +0, OP_RA_RS_SH6_MB6_C, 30<<26 | 1<<2, "rldicr", +0, OP_RA_RS_SH6_MB6_C, 30<<26 | 2<<2, "rldic", +0, OP_RA_RS_SH5_MB5_ME5_C, 21<<26, "rlwinm", +0, OP_RA_RS_RB_MB6_C, 30<<26 | 8<<1, "rldcl", +0, OP_RA_RS_RB_MB6_C, 30<<26 | 9<<1, "rldcr", +0, OP_RA_RS_RB_MB5_ME5_C, 23<<26, "rlwnm", +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 */ +0, OP_clrlsldi, 30<<26 | 2<<2, "clrlsldi", +0, OP_clrldi, 30<<26 | 0<<2, "clrldi", +0, OP_clrrdi, 30<<26 | 1<<2, "clrrdi", +0, OP_extldi, 30<<26 | 0<<2, "extldi", +0, OP_extrdi, 30<<26 | 1<<2, "extrdi", +0, OP_insrdi, 30<<26 | 3<<2, "insrdi", +0, OP_RA_RS_RB_C, 30<<26 | MB6(0) | 8<<1, "rotld", +0, OP_RA_RS_SH6_C, 30<<26 | MB6(0) | 0<<2, "rotldi", +0, OP_rotrdi, 30<<26 | 0<<2, "rotrdi", +0, OP_sldi, 30<<26 | 1<<2, "sldi", +0, OP_srdi, 30<<26 | 0<<2, "srdi", + +/* extended m for word rotation */ +0, OP_clrlslwi, 21<<26, "clrlslwi", +0, OP_clrlwi, 21<<26, "clrlwi", +0, OP_clrrwi, 21<<26, "clrrwi", +0, OP_extlwi, 21<<26, "extlwi", +0, OP_extrwi, 21<<26, "extrwi", +0, OP_inslwi, 20<<26, "inslwi", +0, OP_insrwi, 20<<26, "insrwi", +0, OP_RA_RS_RB_C, 23<<26 | 0<<6 | 31<<1, "rotlw", +0, OP_RA_RS_SH5_C, 21<<26 | 0<<6 | 31<<1, "rotlwi", +0, OP_rotrwi, 21<<26, "rotrwi", +0, OP_slwi, 21<<26, "slwi", +0, OP_srwi, 21<<26, "srwi", /* page 74 */ -0, OP_RS_RA_RB_C, 31<<26 | 27<<1, "sld", -0, OP_RS_RA_RB_C, 31<<26 | 24<<1, "slw", -0, OP_RS_RA_RB_C, 31<<26 | 539<<1, "srd", -0, OP_RS_RA_RB_C, 31<<26 | 536<<1, "srw", -0, OP_RS_RA_SH6_C, 31<<26 | 413<<2, "sradi", -0, OP_RS_RA_SH5_C, 31<<26 | 824<<1, "srawi", -0, OP_RS_RA_RB_C, 31<<26 | 794<<1, "srad", -0, OP_RS_RA_RB_C, 31<<26 | 792<<1, "sraw", +0, OP_RA_RS_RB_C, 31<<26 | 27<<1, "sld", +0, OP_RA_RS_RB_C, 31<<26 | 24<<1, "slw", +0, OP_RA_RS_RB_C, 31<<26 | 539<<1, "srd", +0, OP_RA_RS_RB_C, 31<<26 | 536<<1, "srw", +0, OP_RA_RS_SH6_C, 31<<26 | 413<<2, "sradi", +0, OP_RA_RS_SH5_C, 31<<26 | 824<<1, "srawi", +0, OP_RA_RS_RB_C, 31<<26 | 794<<1, "srad", +0, OP_RA_RS_RB_C, 31<<26 | 792<<1, "sraw", /* page 78 */ 0, OP_RS_SPR, 31<<26 | 467<<1, "mtspr", @@ -295,6 +578,14 @@ 0, OP_RS_FXM, 31<<26 | 0<<21 | 144<<1, "mtcrf", 0, OP_RT, 31<<26 | 0<<21 | 19<<1, "mfcr", +/* extended m for special purpose registers */ +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", + /* Floating point instructions (page 83) */ 0, OP_FRT_RA_D, 48<<26, "lfs", diff --git a/mach/powerpc/as/mach4.c b/mach/powerpc/as/mach4.c index 1ad180de4..99f7f4537 100644 --- a/mach/powerpc/as/mach4.c +++ b/mach/powerpc/as/mach4.c @@ -4,16 +4,33 @@ */ operation - : OP_BF_BFA CR ',' CR { emit4($1 | ($2<<23) | ($4<<18)); } + : OP { emit4($1); } + | OP_BDA bda { emit4($1 | $2); } + | OP_BDL bdl { emit4($1 | $2); } + | OP_BF_BFA CR ',' CR { emit4($1 | ($2<<23) | ($4<<18)); } | OP_BF_FRA_FRB CR ',' FPR ',' FPR { emit4($1 | ($2<<23) | ($4<<16) | ($6<<11)); } | OP_BF_L_RA_RB CR ',' u1 ',' GPR ',' GPR { emit4($1 | ($2<<23) | ($4<<21) | ($6<<16) | ($8<<11)); } | OP_BF_L_RA_SI CR ',' u1 ',' GPR ',' e16 { emit4($1 | ($2<<23) | ($4<<21) | ($6<<16) | $8); } | OP_BF_L_RA_UI CR ',' u1 ',' GPR ',' e16 { emit4($1 | ($2<<23) | ($4<<21) | ($6<<16) | $8); } + | OP_BF_RA_RB cr_opt GPR ',' GPR { emit4($1 | ($2<<23) | ($3<<16) | ($5<<11)); } + | OP_BF_RA_SI cr_opt GPR ',' e16 { emit4($1 | ($2<<23) | ($3<<16) | $5); } + | OP_BF_RA_UI cr_opt GPR ',' e16 { emit4($1 | ($2<<23) | ($3<<16) | $5); } | OP_BF_U_C c CR ',' u4 { emit4($1 | $2 | ($3<<23) | ($5<<12)); } + | OP_BH { emit4($1); } + | OP_BH u2 { emit4($1 | ($2<<11)); } + | OP_BI_BDA u5 ',' bda { emit4($1 | ($2<<16) | $4); } + | OP_BI_BDL u5 ',' bdl { emit4($1 | ($2<<16) | $4); } + | OP_BI_BH u5 opt_bh { emit4($1 | ($2<<16) | $3); } + | OP_BICR_BDA cr_opt bda { emit4($1 | ($2<<18) | $3); } + | OP_BICR_BDL cr_opt bdl { emit4($1 | ($2<<18) | $3); } + | OP_BICR_BH { emit4($1); } + | OP_BICR_BH CR opt_bh { emit4($1 | ($2<<18) | $3); } | OP_BO_BI_BDA u5 ',' u5 ',' bda { emit4($1 | ($2<<21) | ($4<<16) | $6); } | OP_BO_BI_BDL u5 ',' u5 ',' bdl { emit4($1 | ($2<<21) | ($4<<16) | $6); } - | OP_BO_BI_BH u5 ',' u5 ',' u2 { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); } + | OP_BO_BI_BH u5 ',' u5 opt_bh { emit4($1 | ($2<<21) | ($4<<16) | $5); } + | OP_BT_BA_BA u5 ',' u5 { emit4($1 | ($2<<21) | ($4<<16) | ($4<<11)); } | OP_BT_BA_BB u5 ',' u5 ',' u5 { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); } + | OP_BT_BT_BT u5 { emit4($1 | ($2<<21) | ($2<<16) | ($2<<11)); } | OP_BT_C c u5 { emit4($1 | $2 | ($3<<21)); } | OP_FLM_FRB_C c u8 ',' FPR { emit4($1 | $2 | ($3<<17) | ($5<<11)); } | OP_FRS_RA_D FPR ',' e16 '(' GPR ')' { emit4($1 | ($2<<21) | ($6<<16) | $4); } @@ -25,15 +42,35 @@ operation | OP_FRT_RA_D FPR ',' e16 '(' GPR ')' { emit4($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_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 + { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11) | + ($9<<6) | ($11<<1)); } + | OP_RA_RS_RB_MB6_C c GPR ',' GPR ',' GPR ',' u6 + { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11) | MB6($9)); } + | OP_RA_RS_SH5_C c GPR ',' GPR ',' u5 + { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11)); } + | OP_RA_RS_SH5_MB5_ME5_C c GPR ',' GPR ',' u5 ',' u5 ',' u5 + { emit4($1 | $2 | ($5<<21) | ($3<<16) | + ($7<<11) | ($9<<6) | ($11<<1)); } + | OP_RA_RS_SH6_C c GPR ',' GPR ',' u6 + { emit4($1 | $2 | ($5<<21) | ($3<<16) | SH6($7)); } + | OP_RA_RS_SH6_MB6_C c GPR ',' GPR ',' u6 ',' u6 + { emit4($1 | $2 | ($5<<21) | ($3<<16) | SH6($7) | MB6($9)); } | OP_RT GPR { emit4($1 | ($2<<21)); } | OP_RT_RA_C c GPR ',' GPR { emit4($1 | $2 | ($3<<21) | ($5<<16)); } | OP_RT_RA_D GPR ',' e16 '(' GPR ')' { emit4($1 | ($2<<21) | ($6<<16) | $4); } | OP_RT_RA_DS GPR ',' ds '(' GPR ')' { emit4($1 | ($2<<21) | ($6<<16) | $4); } | OP_RT_RA_NB GPR ',' GPR ',' nb { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); } | OP_RT_RA_RB GPR ',' GPR ',' GPR { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); } - | OP_RT_RA_RB_C c GPR ',' GPR ',' GPR { emit4($1 | $2 | ($3<<21) | ($5<<16) | ($7<<11)); } + | 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_RA_SI_subi GPR ',' GPR ',' negate16 { emit4($1 | ($2<<21) | ($4<<16) | $6); } + | OP_RT_RA_SI_subic c GPR ',' GPR ',' negate16 { emit4($1 | ($2<<26) | ($3<<21) | ($5<<16) | $7); } + | OP_RT_RB_RA_C c GPR ',' GPR ',' GPR { emit4($1 | $2 | ($3<<21) | ($7<<16) | ($5<<11)); } + | OP_RT_SI GPR ',' e16 { emit4($1 | ($2<<21) | $4); } | 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)); } @@ -45,21 +82,127 @@ operation | 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_MB5_ME5_C c GPR ',' GPR ',' GPR ',' u5 ',' u5 { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11) | ($9<<6) | ($11<<1)); } - | OP_RS_RA_RB_MB6_C c GPR ',' GPR ',' GPR ',' u6 { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11) | (($9&0x1F)<<6) | (($9&0x20)>>0)); } - | OP_RS_RA_RB_ME6_C c GPR ',' GPR ',' GPR ',' u6 { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11) | (($9&0x1F)<<6) | (($9&0x20)>>0)); } - | OP_RS_RA_SH_MB5_ME5_C c GPR ',' GPR ',' u5 ',' u5 ',' u5 { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11) | ($9<<6) | ($11<<1)); } - | OP_RS_RA_SH_MB6_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_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_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_TOX_RA_RB GPR ',' GPR { emit4($1 | ($2<<16) | ($4<<11)); } + | OP_TOX_RA_SI GPR ',' e16 { emit4($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 */ + | OP_clrlsldi c GPR ',' GPR ',' u6 ',' u6 + { + quad mb = ($7 - $9) & 0x3f; + fit($9 <= $7); + emit4($1 | $2 | ($5<<21) | ($3<<16) | SH6($9) | MB6(mb)); + } + | OP_clrldi c GPR ',' GPR ',' u6 + { + emit4($1 | $2 | ($5<<21) | ($3<<16) | SH6(0) | MB6($7)); + } + | OP_clrrdi c GPR ',' GPR ',' u6 + { + quad me = 63 - $7; + emit4($1 | $2 | ($5<<21) | ($3<<16) | SH6(0) | MB6(me)); + } + | OP_extldi c GPR ',' GPR ',' u6 ',' u6 + { + quad me = ($7 - 1) & 0x3f; + fit($7 > 0); + emit4($1 | $2 | ($5<<21) | ($3<<16) | SH6($9) | MB6(me)); + } + | OP_extrdi c GPR ',' GPR ',' u6 ',' u6 + { + quad sh = ($9 + $7) & 0x3f; + quad mb = (64 - $7) & 0x3f; + fit($7 > 0); + emit4($1 | $2 | ($5<<21) | ($3<<16) | SH6(sh) | MB6(mb)); + } + | OP_rotrdi c GPR ',' GPR ',' u6 + { + quad sh = (64 - $7) & 0x3f; + emit4($1 | $2 | ($5<<21) | ($3<<16) | SH6(sh) | MB6(0)); + } + | OP_sldi c GPR ',' GPR ',' u6 + { + quad me = 63 - $7; + emit4($1 | $2 | ($5<<21) | ($3<<16) | SH6($7) | MB6(me)); + } + | OP_srdi c GPR ',' GPR ',' u6 + { + quad sh = (64 - $7) & 0x3f; + emit4($1 | $2 | ($5<<21) | ($3<<16) | SH6(sh) | MB6($7)); + } + | OP_clrlslwi c GPR ',' GPR ',' u5 ',' u5 + { + quad mb = ($7 - $9) & 0x1f; + quad me = 31 - $9; + fit($9 <= $7); + emit4($1 | $2 | ($5<<21) | ($3<<16) | + ($9<<11) | (mb<<6) | (me<<1)); + } + | OP_clrlwi c GPR ',' GPR ',' u5 + { + emit4($1 | $2 | ($5<<21) | ($3<<16) | + (0<<11) | ($7<<6) | (31<<1)); + } + | OP_clrrwi c GPR ',' GPR ',' u5 + { + quad me = 31 - $7; + emit4($1 | $2 | ($5<<21) | ($3<<16) | + (0<<11) | (0<<6) | (me<<1)); + } + | OP_extlwi c GPR ',' GPR ',' u5 ',' u5 + { + quad me = ($7 - 1) & 0x1f; + fit($7 > 0); + emit4($1 | $2 | ($5<<21) | ($3<<16) | + ($9<<11) | (0<<6) | (me<<1)); + } + | OP_extrwi c GPR ',' GPR ',' u5 ',' u5 + { + quad sh = ($9 + $7) & 0x1f; + quad mb = (32 - $7) & 0x1f; + fit($7 > 0); + emit4($1 | $2 | ($5<<21) | ($3<<16) | + (sh<<11) | (mb<<6) | (31<<1)); + } + | OP_inslwi c GPR ',' GPR ',' u5 ',' u5 + { + quad sh = (32 - $9) & 0x1f; + quad me = ($9 + $7 - 1) & 0x1f; + fit($7 > 0); + emit4($1 | $2 | ($5<<21) | ($3<<16) | + (sh<<11) | ($9<<6) | (me<<1)); + } + | OP_insrwi c GPR ',' GPR ',' u5 ',' u5 + { + quad sh = (32 - $9 - $7) & 0x1f; + quad me = ($9 + $7 - 1) & 0x1f; + fit($7 > 0); + emit4($1 | $2 | ($5<<21) | ($3<<16) | + (sh<<11) | ($9<<6) | (me<<1)); + } + | OP_rotrwi c GPR ',' GPR ',' u5 + { + quad sh = (32 - $7) & 0x1f; + emit4($1 | $2 | ($5<<21) | ($3<<16) | + (sh<<11) | (0<<6) | (31<<1)); + } + | OP_slwi c GPR ',' GPR ',' u5 + { + quad me = 31 - $7; + emit4($1 | $2 | ($5<<21) | ($3<<16) | + ($7<<11) | (0<<6) | (me<<1)); + } + | OP_srwi c GPR ',' GPR ',' u5 + { + quad sh = (32 - $7) & 0x1f; + emit4($1 | $2 | ($5<<21) | ($3<<16) | + (sh<<11) | ($7<<6) | (31<<1)); + } ; c @@ -80,6 +223,17 @@ e16 | OP_LO ASC_LPAR expr ASC_RPAR { $$ = emit_lo(&$3); } ; +negate16 + : absexp + { + /* To encode subi, we negate the immediate value, then + * it must fit as signed 16-bit. */ + $$ = -$1; + fit(fitx($$, 16)); + $$ = (uint16_t) $$; + } + ; + u8 : absexp { @@ -143,6 +297,19 @@ u2 } ; +/* Optional comma, branch hint. */ +opt_bh + : /* nothing */ { $$ = 0; } + | ',' u2 { $$ = ($2<<11); } + +/* + * Optional condition register, comma. This checks if the token is a + * CR register name. This wouldn't work if we allowed CR as a number. + */ +cr_opt + : /* nothing */ { $$ = 0; } + | CR ',' { $$ = $1; } + ds : e16 { @@ -251,14 +418,3 @@ spr_num $$ = ($1 >> 5) | (($1 & 0x1f) << 5); } ; - -powerpcfixup - : expr - { - quad type = $1.typ & S_TYP; - quad val = $1.val; - if (type == S_ABS) - serror(".powerpcfixup is useless on absolute values"); - newrelo($1.typ, RELOPPC | FIXUPFLAGS); - } - ; diff --git a/mach/powerpc/libem/aar4.s b/mach/powerpc/libem/aar4.s index 2c65af643..5e4155091 100644 --- a/mach/powerpc/libem/aar4.s +++ b/mach/powerpc/libem/aar4.s @@ -1,12 +1,5 @@ -# -! $Source$ -! $State$ -! $Revision$ - -#include "powerpc.h" - .sect .text - + ! Index into a bounds-checked array. ! ! On entry: @@ -20,19 +13,20 @@ .define .aar4 .aar4: - li32 r0, .trap_earray + lis r0, hi16[.trap_earray] + ori r0, r0, lo16[.trap_earray] mtspr ctr, r0 ! load CTR with trap address lwz r0, 0(r3) subf. r4, r0, r4 ! adjust range - bcctr IFTRUE, LT, 0 ! check lower bound - + bltctr ! check lower bound + lwz r0, 4(r3) - cmpl cr0, 0, r4, r3 - bcctr IFFALSE, LT, 0 ! check upper bound - + cmplw r4, r3 + bgectr ! check upper bound + lwz r0, 8(r3) mullw r4, r4, r0 ! scale index add r3, r4, r5 ! calculate element address - - bclr ALWAYS, 0, 0 + + blr diff --git a/mach/powerpc/libem/and.s b/mach/powerpc/libem/and.s index 727d79ec0..cb4e1e54a 100644 --- a/mach/powerpc/libem/and.s +++ b/mach/powerpc/libem/and.s @@ -1,5 +1,3 @@ -#include "powerpc.h" - .sect .text ! Set intersection. @@ -12,7 +10,7 @@ mr r4, sp ! r4 = ptr to set a add r5, sp, r3 ! r5 = ptr to set b - rlwinm r6, r3, 30, 2, 31 + srwi r6, r3, 2 mtspr ctr, r6 ! ctr = r3 / 4 1: lwz r7, 0(r4) @@ -21,6 +19,6 @@ stw r8, 0(r5) addi r4, r4, 4 addi r5, r5, 4 - bc DNZ, 0, 1b ! loop ctr times + bdnz 1b ! loop ctr times add sp, sp, r3 - bclr ALWAYS, 0, 0 + blr diff --git a/mach/powerpc/libem/build.lua b/mach/powerpc/libem/build.lua index 786be4e11..466a28fb3 100644 --- a/mach/powerpc/libem/build.lua +++ b/mach/powerpc/libem/build.lua @@ -1,14 +1,12 @@ for _, plat in ipairs(vars.plats) do acklibrary { name = "headers_"..plat, - hdrs = { "./*.h" } } acklibrary { name = "lib_"..plat, srcs = { - "./*.s", -- zer.s - "./*.e", + "./*.s", }, vars = { plat = plat }, deps = { diff --git a/mach/powerpc/libem/cfi8.s b/mach/powerpc/libem/cfi8.s index 7142c694b..9a87e99ae 100644 --- a/mach/powerpc/libem/cfi8.s +++ b/mach/powerpc/libem/cfi8.s @@ -1,10 +1,3 @@ -# -! $Source$ -! $State$ -! $Revision$ - -#include "powerpc.h" - .sect .text ! Converts a 64-bit double into a 32-bit integer. @@ -17,4 +10,4 @@ fctiwz f0, f0 stfd f0, 0(sp) addi sp, sp, 4 - bclr ALWAYS, 0, 0 ! ...and return + blr diff --git a/mach/powerpc/libem/cfu8.s b/mach/powerpc/libem/cfu8.s index 758df8572..915f84dd2 100644 --- a/mach/powerpc/libem/cfu8.s +++ b/mach/powerpc/libem/cfu8.s @@ -1,10 +1,3 @@ -# -! $Source$ -! $State$ -! $Revision$ - -#include "powerpc.h" - .sect .text ! Converts a 64-bit double into a 32-bit unsigned integer. @@ -13,17 +6,17 @@ .define .cfu8 .cfu8: - li32 r3, .fd_00000000 - lfd f0, 0(r3) ! f0 = 0.0 - + lis r3, ha16[.fd_00000000] + lfd f0, lo16[.fd_00000000](r3) ! f0 = 0.0 + lfd f1, 0(sp) ! value to be converted - li32 r3, .fd_FFFFFFFF - lfd f3, 0(r3) ! f3 = 0xFFFFFFFF + lis r3, ha16[.fd_FFFFFFFF] + lfd f3, lo16[.fd_FFFFFFFF](r3) ! f3 = 0xFFFFFFFF + + lis r3, ha16[.fd_80000000] + lfd f4, lo16[.fd_80000000](r3) ! f4 = 0x80000000 - li32 r3, .fd_80000000 - lfd f4, 0(r3) ! f4 = 0x80000000 - fsel f2, f1, f1, f0 fsub f5, f3, f1 fsel f2, f5, f2, f3 @@ -34,11 +27,11 @@ stfd f2, 0(sp) addi sp, sp, 4 - - bclr IFTRUE, LT, 0 - + + bltlr + lwz r3, 0(sp) xoris r3, r3, 0x8000 stw r3, 0(sp) - bclr ALWAYS, 0, 0 + blr diff --git a/mach/powerpc/libem/cif8.s b/mach/powerpc/libem/cif8.s index d2c82e54e..13abbcade 100644 --- a/mach/powerpc/libem/cif8.s +++ b/mach/powerpc/libem/cif8.s @@ -1,9 +1,4 @@ -# -! $Source$ -! $State$ -! $Revision$ - -#include "powerpc.h" +.sect .text; .sect .rom; .sect .data; .sect .bss .sect .text @@ -14,22 +9,22 @@ .define .cif8 .cif8: addi sp, sp, -4 ! make space for the double - + lwz r3, 4(sp) xoris r3, r3, 0x8000 stw r3, 4(sp) ! flip sign of integer value - + addis r3, r0, 0x4330 stw r3, 0(sp) ! set high word to construct a double - + lfd f0, 0(sp) ! load value - li32 r3, pivot - lfd f1, 0(r3) ! load pivot value + lis r3, ha16[pivot] + lfd f1, lo16[pivot](r3) ! load pivot value fsub f0, f0, f1 ! adjust - + stfd f0, 0(sp) ! save value again... - bclr ALWAYS, 0, 0 ! ...and return + blr ! ...and return .sect .rom pivot: diff --git a/mach/powerpc/libem/cms.s b/mach/powerpc/libem/cms.s index 53cb65691..30aaccd20 100644 --- a/mach/powerpc/libem/cms.s +++ b/mach/powerpc/libem/cms.s @@ -1,5 +1,3 @@ -#include "powerpc.h" - .sect .text ! Compare sets a, b. @@ -12,21 +10,21 @@ mr r4, sp ! r4 = ptr to set a add r5, sp, r3 ! r5 = ptr to set b mr r6, r3 ! r6 = size - rlwinm r3, r3, 30, 2, 31 + srwi r3, r3, 2 mtspr ctr, r3 ! ctr = size / 4 1: lwz r7, 0(r4) lwz r8, 0(r5) - cmp cr0, 0, r7, r8 ! compare words in sets + cmpw cr0, r7, r8 ! compare words in sets addi r4, r4, 4 addi r5, r5, 4 - bc IFFALSE, EQ, 2f ! branch if not equal - bc DNZ, 0, 1b ! loop ctr times + bne cr0, 2f ! branch if not equal + bdnz 1b ! loop ctr times addi r3, r0, 0 ! equal: return 0 b 3f 2: addi r3, r0, 1 ! not equal: return 1 3: - rlwinm r6, r6, 1, 0, 30 ! r6 = size * 2 + slwi r6, r6, 1 ! r6 = size * 2 add sp, sp, r6 ! remove sets from stack - bclr ALWAYS, 0, 0 + blr diff --git a/mach/powerpc/libem/com.s b/mach/powerpc/libem/com.s index 084eeeb62..3168cfe17 100644 --- a/mach/powerpc/libem/com.s +++ b/mach/powerpc/libem/com.s @@ -1,5 +1,3 @@ -#include "powerpc.h" - .sect .text ! Set complement. @@ -11,12 +9,12 @@ addi sp, sp, 4 mr r4, sp ! r4 = pointer to set a - rlwinm r5, r3, 30, 2, 31 + srwi r5, r3, 2 mtspr ctr, r5 ! ctr = r3 / 4 1: lwz r6, 0(r4) nor r6, r6, r6 ! complement of word stw r6, 0(r4) addi r4, r4, 4 - bc DNZ, 0, 1b ! loop ctr times - bclr ALWAYS, 0, 0 + bdnz 1b ! loop ctr times + blr diff --git a/mach/powerpc/libem/csa.s b/mach/powerpc/libem/csa.s index 88e6e176a..3898241c4 100644 --- a/mach/powerpc/libem/csa.s +++ b/mach/powerpc/libem/csa.s @@ -1,10 +1,3 @@ -# -! $Source$ -! $State$ -! $Revision$ - -#include "powerpc.h" - .sect .text ! this is not a subroutine, but just a @@ -25,23 +18,17 @@ lwz r5, 4(r3) ! fetch lower bound subf. r4, r5, r4 ! adjust value - bcctr IFTRUE, LT, 0 ! jump to default if out of range - + bltctr ! jump to default if out of range + lwz r5, 8(r3) ! fetch range - cmp cr0, 0, r4, r5 - bcctr IFTRUE, GT, 0 ! jump to default if out of range - + cmplw r4, r5 + bgtctr ! jump to default if out of range + addi r3, r3, 12 ! skip header - rlwinm r4, r4, 2, 0, 31-2 ! scale value (<<2) - b 1f -1: + slwi r4, r4, 2 ! scale value (<<2) lwzx r5, r3, r4 ! load target - b 1f -1: mtspr ctr, r5 - + or. r5, r5, r5 ! test it - b 1f -1: - bcctr IFFALSE, EQ, 0 ! jump to target if non-zero + bnectr ! jump to target if non-zero b .trap_ecase ! otherwise trap diff --git a/mach/powerpc/libem/csb.s b/mach/powerpc/libem/csb.s index a8df85d7f..571bfc210 100644 --- a/mach/powerpc/libem/csb.s +++ b/mach/powerpc/libem/csb.s @@ -1,10 +1,3 @@ -# -! $Source$ -! $State$ -! $Revision$ - -#include "powerpc.h" - .sect .text ! this is not a subroutine, but just a @@ -22,21 +15,21 @@ lwz r5, 0(r3) ! load default mtspr ctr, r5 - + lwz r6, 4(r3) ! fetch count - + 1: or. r6, r6, r6 ! test count - bcctr IFTRUE, EQ, 0 ! exit if zero + beqctr ! exit if zero addi r6, r6, -1 ! otherwise decrement - + lwzu r7, 8(r3) ! fetch target index, increment pointer - cmp cr0, 0, r4, r7 ! compare with value - bc IFFALSE, EQ, 1b ! if not equal, go again - + cmpw r4, r7 ! compare with value + bne 1b ! if not equal, go again + lwz r7, 4(r3) ! fetch target address mtspr ctr, r7 - + or. r7, r7, r7 ! test it - bcctr IFFALSE, EQ, 0 ! jump to target if non-zero + bnectr ! jump to target if non-zero b .trap_ecase ! otherwise trap diff --git a/mach/powerpc/libem/cuf8.s b/mach/powerpc/libem/cuf8.s index 5d5a12988..ce9932aa1 100644 --- a/mach/powerpc/libem/cuf8.s +++ b/mach/powerpc/libem/cuf8.s @@ -1,10 +1,3 @@ -# -! $Source$ -! $State$ -! $Revision$ - -#include "powerpc.h" - .sect .text ! Converts a 32-bit unsigned integer into a 64-bit double. @@ -14,18 +7,18 @@ .define .cuf8 .cuf8: addi sp, sp, -4 ! make space for the double - - addis r3, r0, 0x4330 + + lis r3, 0x4330 stw r3, 0(sp) ! set high word to construct a double - + lfd f0, 0(sp) ! load value - - li32 r3, pivot - lfd f1, 0(r3) ! load pivot value + + lis r3, ha16[pivot] + lfd f1, lo16[pivot](r3) ! load pivot value fsub f0, f0, f1 ! adjust - + stfd f0, 0(sp) ! save value again... - bclr ALWAYS, 0, 0 ! ...and return + blr ! ...and return .sect .rom pivot: diff --git a/mach/powerpc/libem/fd_00000000.s b/mach/powerpc/libem/fd_00000000.s index cefa91b8e..8ffe44a24 100644 --- a/mach/powerpc/libem/fd_00000000.s +++ b/mach/powerpc/libem/fd_00000000.s @@ -1,10 +1,5 @@ -# -! $Source$ -! $State$ -! $Revision$ +.sect .text; .sect .rom; .sect .data; .sect .bss -#include "powerpc.h" - .sect .rom ! Contains a handy double-precision zero. (Also works as a single-precision diff --git a/mach/powerpc/libem/fd_80000000.s b/mach/powerpc/libem/fd_80000000.s index 50eacd586..5c153bba8 100644 --- a/mach/powerpc/libem/fd_80000000.s +++ b/mach/powerpc/libem/fd_80000000.s @@ -1,10 +1,5 @@ -# -! $Source$ -! $State$ -! $Revision$ +.sect .text; .sect .rom; .sect .data; .sect .bss -#include "powerpc.h" - .sect .rom ! Contains a handy double-precision 0x80000000. diff --git a/mach/powerpc/libem/fd_FFFFFFFF.s b/mach/powerpc/libem/fd_FFFFFFFF.s index 9218f2726..88cf04bd9 100644 --- a/mach/powerpc/libem/fd_FFFFFFFF.s +++ b/mach/powerpc/libem/fd_FFFFFFFF.s @@ -1,15 +1,10 @@ -# -! $Source$ -! $State$ -! $Revision$ +.sect .text; .sect .rom; .sect .data; .sect .bss -#include "powerpc.h" - .sect .rom ! Contains a handy double-precision 0xFFFFFFFF. .define .fd_FFFFFFFF -.fd_FFFFFFFF: +.fd_FFFFFFFF: !float 4.294967295e+9 sz 8 .data1 0101,0357,0377,0377,0377,0340,00,00 diff --git a/mach/powerpc/libem/fef8.s b/mach/powerpc/libem/fef8.s index fc72b04f2..f71ab8e38 100644 --- a/mach/powerpc/libem/fef8.s +++ b/mach/powerpc/libem/fef8.s @@ -1,4 +1,4 @@ -#include "powerpc.h" +.sect .text; .sect .rom; .sect .data; .sect .bss .sect .text @@ -10,46 +10,44 @@ ! r3 = fraction, high word (bits 0..31) ! r4 = fraction, low word (bits 32..63) ! r5 = exponent -! Kills: cr0 f0 f1 r6 r7 .define .fef8 .fef8: ! IEEE double-precision format: ! sign exponent fraction ! 0 1..11 12..63 - rlwinm r6, r3, 12, 21, 31 ! r6 = IEEE exponent - addis r7, r0, 0x7ff0 ! r7 = exponent mask + extrwi r6, r3, 11, 1 ! r6 = IEEE exponent addi r5, r6, -1022 ! r5 = true exponent - cmpi cr0, 0, r6, 2047 - bclr IFTRUE, EQ, 0 ! return if infinity or NaN - cmpi cr0, 0, r6, 0 - bc IFFALSE, EQ, 1f ! jump if normalized number + cmpwi r6, 2047 + beqlr ! return if infinity or NaN + cmpwi r6, 0 + bne 1f ! jump if normalized number ! Got denormalized number or zero, probably zero. - rlwinm r6, r3, 0, 12, 31 + extrwi r6, r3, 22, 12 addi r5, r0, 0 ! r5 = true exponent = 0 or. r6, r6, r4 ! r6 = high|low fraction - bclr IFTRUE, EQ, 0 ! return if zero + beqlr ! return if zero ! Got denormalized number, not zero. stwu r4, -4(sp) stwu r3, -4(sp) - li32 r6, _2_64 lfd f0, 0(sp) - lfd f1, 0(r6) + lis r6, ha16[_2_64] + lfd f1, lo16[_2_64](r6) fmul f0, f0, f1 ! multiply it by 2**64 stfd f0, 0(sp) lwz r3, 0(sp) lwz r4, 4(sp) - rlwinm r6, r3, 12, 21, 31 ! r6 = IEEE exponent + extrwi r6, r3, 11, 1 ! r6 = IEEE exponent addi sp, sp, 8 addi r5, r6, -1022 - 64 ! r5 = true exponent 1: ! Put fraction in [0.5, 1) or (-1, -0.5] by setting its ! exponent to true 0, IEEE 1022. - andc r3, r3, r7 ! clear old exponent + rlwinm r3, r3, 0, 12, 0 ! clear old exponent oris r3, r3, 1022 << 4 ! set new exponent - bclr ALWAYS, 0, 0 + blr .sect .rom _2_64: diff --git a/mach/powerpc/libem/fif8.s b/mach/powerpc/libem/fif8.s index a26c77830..eda9b04f2 100644 --- a/mach/powerpc/libem/fif8.s +++ b/mach/powerpc/libem/fif8.s @@ -1,5 +1,3 @@ -#include "powerpc.h" - .sect .text ! Multiplies two double-precision floats, then splits the product into @@ -9,7 +7,6 @@ ! Yields: ! f1 = fraction ! f2 = integer -! Kills: cr0 f1 f2 r3 r4 r5 r6 .define .fif8 .fif8: @@ -25,17 +22,16 @@ ! 0 to 51, then the IEEE fraction has that many integer bits. ! (IEEE has an implicit 1 before its fraction. If the IEEE ! fraction has 0 integer bits, we still have an integer.) - rlwinm r5, r3, 12, 21, 31 ! r5 = IEEE exponent + extrwi r5, r3, 11, 1 ! r5 = IEEE exponent addic. r5, r5, -1023 ! r5 = nr of integer bits - bc IFTRUE, LT, no_int - cmpi cr0, 0, r5, 21 - bc IFTRUE, LT, small_int - cmpi cr0, 0, r5, 52 - bc IFTRUE, LT, big_int + blt no_int + cmpwi r5, 21 + blt small_int + cmpwi r5, 52 + blt big_int - ! f1 is an integer without fraction. Jump to calculate - ! fraction f1 = f2 - f1. It will be zero (or perhaps NaN). - fmr f2, f1 + ! f1 is an integer without fraction (or infinity or NaN). + fmr f2, f1 ! integer = f1 b subtract no_int: @@ -46,17 +42,17 @@ no_int: small_int: ! f1 has r5 = 0 to 20 integer bits in the IEEE fraction. ! High word has 20 - r5 fraction bits. - addi r6, r0, 20 + li r6, 20 subf r6, r5, r6 srw r3, r3, r6 - addi r4, r0, 0 ! clear low word + li r4, 0 ! clear low word slw r3, r3, r6 ! clear fraction in high word b move_int big_int: ! f1 has r5 = 21 to 51 to integer bits. ! Low word has 52 - r5 fraction bits. - addi r6, r0, 52 + li r6, 52 subf r6, r5, r6 srw r4, r4, r6 slw r4, r4, r6 ! clear fraction in low word @@ -68,4 +64,4 @@ subtract: fsub f1, f1, f2 ! fraction = value - integer done: addi sp, sp, 8 ! restore stack pointer - bclr ALWAYS, 0, 0 + blr diff --git a/mach/powerpc/libem/inn.s b/mach/powerpc/libem/inn.s index 9770ac094..8925e776e 100644 --- a/mach/powerpc/libem/inn.s +++ b/mach/powerpc/libem/inn.s @@ -1,4 +1,4 @@ -#include "powerpc.h" +# .sect .text @@ -14,13 +14,13 @@ addi r5, sp, 8 /* r5 = base address of bit set */ rlwinm r6, r4, 29, 3, 29 /* r6 = byte index of word in set */ - andi. r7, r4, 31 /* r7 = bit within word */ + extrwi r7, r4, 5, 27 /* r7 = bit number within word */ - lwzx r8, r5, r6 /* r8 = individual byte from set */ - sraw r8, r8, r7 - rlwinm r8, r8, 0, 31, 31 + lwzx r8, r5, r6 /* r8 = individual word from set */ + srw r8, r8, r7 + extrwi r8, r8, 1, 31 addi sp, sp, 8 /* retract over the two words */ add sp, sp, r3 /* retract over bitfield */ stwu r8, -4(sp) /* push result */ - bclr ALWAYS, 0, 0 /* return */ + blr /* return */ diff --git a/mach/powerpc/libem/ior.s b/mach/powerpc/libem/ior.s index 363799e1d..e6cd1844e 100644 --- a/mach/powerpc/libem/ior.s +++ b/mach/powerpc/libem/ior.s @@ -1,5 +1,3 @@ -#include "powerpc.h" - .sect .text ! Set union. @@ -12,7 +10,7 @@ mr r4, sp ! r4 = ptr to set a add r5, sp, r3 ! r5 = ptr to set b - rlwinm r6, r3, 30, 2, 31 + srwi r6, r3, 2 mtspr ctr, r6 ! ctr = r3 / 4 1: lwz r7, 0(r4) @@ -21,6 +19,6 @@ stw r8, 0(r5) addi r4, r4, 4 addi r5, r5, 4 - bc DNZ, 0, 1b ! loop ctr times + bdnz 1b ! loop ctr times add sp, sp, r3 - bclr ALWAYS, 0, 0 + blr diff --git a/mach/powerpc/libem/lar4.s b/mach/powerpc/libem/lar4.s index 6375979c4..2f5c3683c 100644 --- a/mach/powerpc/libem/lar4.s +++ b/mach/powerpc/libem/lar4.s @@ -1,6 +1,3 @@ -# -#include "powerpc.h" - .sect .text ! Load from bounds-checked array. @@ -18,19 +15,19 @@ ! r3 = ptr to element ! r0 = size of element - cmpi cr0, 0, r0, 1 - bc IFFALSE, EQ, 1f + cmpwi r0, 1 + bne 1f ! Load 1 byte. lbz r4, 0(r3) stwu r4, -4(sp) - bclr ALWAYS, 0, 0 + blr 1: - cmpi cr0, 0, r0, 2 - bc IFFALSE, EQ, 2f + cmpwi r0, 2 + bne 2f ! Load 2 bytes. lhz r4, 0(r3) stwu r4, -4(sp) - bclr ALWAYS, 0, 0 + blr 2: ! Load r0 bytes, where r0 must be a positive multiple of 4. subf sp, r0, sp ! move stack pointer down @@ -39,5 +36,5 @@ addic. r5, r5, -4 ! r5 -= 4 lwzx r4, r5, r3 stwx r4, r5, sp - bc IFTRUE, GT, 3b ! loop if r5 > 0 - bclr ALWAYS, 0, 0 + bgt 3b ! loop if r5 > 0 + blr diff --git a/mach/powerpc/libem/los.s b/mach/powerpc/libem/los.s index f867fe770..2d412bce8 100644 --- a/mach/powerpc/libem/los.s +++ b/mach/powerpc/libem/los.s @@ -1,10 +1,3 @@ -# -! $Source$ -! $State$ -! $Revision$ - -#include "powerpc.h" - .sect .text ! Loads a variable-sized structure onto the stack. @@ -15,32 +8,32 @@ .define .los .los: ! These sizes are handled specially. - - cmpi cr0, 0, r3, 1 - bc IFFALSE, GT, size1 - - cmpi cr0, 0, r3, 2 - bc IFFALSE, GT, size2 - - cmpi cr0, 0, r3, 4 - bc IFFALSE, GT, size4 - + + cmplwi r3, 1 + ble size1 + + cmplwi r3, 2 + ble size2 + + cmplwi r3, 4 + ble size4 + ! Variable-sized structure. - + addi r3, r3, 3 - andi. r3, r3, ~3 ! align size - + clrrwi r3, r3, 2 ! align size + add r4, r4, r3 ! adjust address to top of block - srawi r3, r3, 2 ! convert size to the number of words + srwi r3, r3, 2 ! convert size to the number of words mtspr ctr, r3 - + 1: lwzu r5, -4(r4) stwu r5, -4(sp) - bc DNZ, 0, 1b ! decrement CTR, jump if non-zero - bclr ALWAYS, 0, 0 - + bdnz 1b ! decrement CTR, jump if non-zero + blr + size1: lbz r3, 0(r4) b 1f @@ -51,4 +44,4 @@ size4: lwz r3, 0(r4) 1: stwu r3, -4(sp) - bclr ALWAYS, 0, 0 + blr diff --git a/mach/powerpc/libem/powerpc.h b/mach/powerpc/libem/powerpc.h deleted file mode 100644 index 3540a6856..000000000 --- a/mach/powerpc/libem/powerpc.h +++ /dev/null @@ -1,22 +0,0 @@ -# -! $Source$ -! $State$ -! $Revision$ - -! Declare segments (the order is important). - -.sect .text -.sect .rom -.sect .data -.sect .bss - -#define IFFALSE 4 -#define IFTRUE 12 -#define ALWAYS 20 -#define DNZ 16 - -#define LT 0 -#define GT 1 -#define EQ 2 -#define OV 3 - diff --git a/mach/powerpc/libem/rck.s b/mach/powerpc/libem/rck.s index 0d5717f16..9008be610 100644 --- a/mach/powerpc/libem/rck.s +++ b/mach/powerpc/libem/rck.s @@ -1,5 +1,3 @@ -#include "powerpc.h" - .sect .text ! Bounds check. Traps if the value is out of range. @@ -12,11 +10,11 @@ addi sp, sp, 4 ! leave value on stack lwz r5, 0 (r3) - cmp cr0, 0, r4, r5 - bc IFTRUE, LT, .trap_erange + cmpw r4, r5 + blt .trap_erange lwz r5, 4 (r3) - cmp cr0, 0, r4, r5 - bc IFTRUE, GT, .trap_erange + cmpw r4, r5 + bgt .trap_erange - bclr ALWAYS, 0, 0 + blr diff --git a/mach/powerpc/libem/ret.s b/mach/powerpc/libem/ret.s index cca79ae86..c498af240 100644 --- a/mach/powerpc/libem/ret.s +++ b/mach/powerpc/libem/ret.s @@ -1,19 +1,12 @@ -# -! $Source$ -! $State$ -! $Revision$ - -#include "powerpc.h" - .sect .text - + ! Standard boilerplate for returning from functions. .define .ret .ret: lwz r0, 4(fp) mtspr lr, r0 - lwz r0, 0(fp) ! our stack frame becomes invalid as soon as... - addi sp, fp, 8 ! ...we change sp - or fp, r0, r0 - bclr ALWAYS, 0, 0 + lwz r0, 0(fp) ! our stack frame becomes invalid as soon as... + addi sp, fp, 8 ! ...we change sp + mr fp, r0 + blr diff --git a/mach/powerpc/libem/sar4.s b/mach/powerpc/libem/sar4.s index 0c1368af1..7c9778958 100644 --- a/mach/powerpc/libem/sar4.s +++ b/mach/powerpc/libem/sar4.s @@ -1,6 +1,3 @@ -# -#include "powerpc.h" - .sect .text ! Store to bounds-checked array. @@ -18,21 +15,21 @@ ! r3 = ptr to element ! r0 = size of element - cmpi cr0, 0, r0, 1 - bc IFFALSE, EQ, 1f + cmpwi r0, 1 + bne 1f ! Store 1 byte. lwz r4, 0(sp) addi sp, sp, 4 stb r4, 0(r3) - bclr ALWAYS, 0, 0 + blr 1: - cmpi cr0, 0, r0, 2 - bc IFFALSE, EQ, 2f + cmpwi r0, 2 + bne 2f ! Store 2 bytes. lwz r4, 0(sp) addi sp, sp, 4 sth r4, 0(r3) - bclr ALWAYS, 0, 0 + blr 2: ! Store r0 bytes, where r0 must be a positive multiple of 4. or r5, r0, r0 ! index r5 = length r0 @@ -40,6 +37,6 @@ addic. r5, r5, -4 ! r5 -= 4 lwzx r4, r5, sp stwx r4, r5, r3 - bc IFTRUE, GT, 3b ! loop if r5 > 0 + bgt 3b ! loop if r5 > 0 add sp, r0, sp ! move stack pointer up - bclr ALWAYS, 0, 0 + blr diff --git a/mach/powerpc/libem/set.s b/mach/powerpc/libem/set.s index b42881cd7..3c4a9e579 100644 --- a/mach/powerpc/libem/set.s +++ b/mach/powerpc/libem/set.s @@ -1,5 +1,3 @@ -#include "powerpc.h" - .sect .text ! Create singleton set. @@ -11,22 +9,22 @@ lwz r4, 4 (sp) addi sp, sp, 8 - rlwinm r7, r3, 30, 2, 31 + srwi r7, r3, 2 neg r5, r3 add sp, sp, r5 ! allocate set mr r6, sp ! r6 = ptr to set mtspr ctr, r7 ! ctr = r3 / 4 1: - rlwinm. r7, r4, 0, 0, 26 ! r7 = r4 & ~31 - bc IFTRUE, EQ, 2f ! branch if r4 in 0..31 - addi r5, r0, 0 ! no bit, word is zero + clrrwi. r7, r4, 5 ! r7 = r4 & ~31 + beq 2f ! branch if r4 in 0..31 + li r5, 0 ! no bit, word is zero b 3f 2: - addi r5, r0, 1 + li r5, 1 slw r5, r5, r4 ! yes bit, set bit in word 3: stw r5, 0(r6) ! store word in set addi r4, r4, -32 addi r6, r6, 4 - bc DNZ, 0, 1b ! loop ctr times - bclr ALWAYS, 0, 0 + bdnz 1b ! loop ctr times + blr diff --git a/mach/powerpc/libem/sts.s b/mach/powerpc/libem/sts.s index 2f8022ad9..411b0fb66 100644 --- a/mach/powerpc/libem/sts.s +++ b/mach/powerpc/libem/sts.s @@ -1,10 +1,3 @@ -# -! $Source$ -! $State$ -! $Revision$ - -#include "powerpc.h" - .sect .text ! Stores a variable-sized structure from the stack. @@ -15,35 +8,35 @@ .define .sts .sts: ! These sizes are handled specially. - + lwz r5, 0(sp) - cmpi cr0, 0, r3, 1 - bc IFFALSE, GT, size1 - - cmpi cr0, 0, r3, 2 - bc IFFALSE, GT, size2 - - cmpi cr0, 0, r3, 4 - bc IFFALSE, GT, size4 - + cmplwi r3, 1 + ble size1 + + cmplwi r3, 2 + ble size2 + + cmplwi r3, 4 + ble size4 + ! Variable-sized structure. - + addi r3, r3, 3 - andi. r3, r3, ~3 ! align size - - srawi r3, r3, 2 ! convert size to the number of words + clrrwi r3, r3, 2 ! align size + + srwi r3, r3, 2 ! convert size to the number of words mtspr ctr, r3 - + 1: lwz r5, 0(sp) addi sp, sp, 4 stw r5, 0(r4) addi r4, r4, 4 - bc DNZ, 0, 1b ! decrement CTR, jump if non-zero - bclr ALWAYS, 0, 0 - + bdnz 1b ! decrement CTR, jump if non-zero + blr + size1: stb r5, 0(r4) b 1f @@ -54,4 +47,4 @@ size4: stw r5, 0(r4) 1: addi sp, sp, 4 - bclr ALWAYS, 0, 0 + blr diff --git a/mach/powerpc/libem/tge.s b/mach/powerpc/libem/tge.s deleted file mode 100644 index 4740d8436..000000000 --- a/mach/powerpc/libem/tge.s +++ /dev/null @@ -1,46 +0,0 @@ -# -! $Source$ -! $State$ -! $Revision$ - -#include "powerpc.h" - -.sect .rom - -! Lookup table for tge. - -.define .teq_table -.teq_table: - .data4 1 ! . . - .data4 0 ! . G - .data4 0 ! L . - -.define .tne_table -.tne_table: - .data4 0 ! . . - .data4 1 ! . G - .data4 1 ! L . - -.define .tgt_table -.tgt_table: - .data4 0 ! . . - .data4 1 ! . G - .data4 0 ! L . - -.define .tge_table -.tge_table: - .data4 1 ! . . - .data4 1 ! . G - .data4 0 ! L . - -.define .tlt_table -.tlt_table: - .data4 0 ! . . - .data4 0 ! . G - .data4 1 ! L . - -.define .tle_table -.tle_table: - .data4 1 ! . . - .data4 0 ! . G - .data4 1 ! L . diff --git a/mach/powerpc/libem/xor.s b/mach/powerpc/libem/xor.s index 9d4bc76b9..acb02a032 100644 --- a/mach/powerpc/libem/xor.s +++ b/mach/powerpc/libem/xor.s @@ -1,5 +1,3 @@ -#include "powerpc.h" - .sect .text ! Set symmetric difference. @@ -10,7 +8,7 @@ .xor: mr r4, sp ! r4 = ptr to set a add r5, sp, r3 ! r5 = ptr to set b - rlwinm r6, r3, 30, 2, 31 + srwi r6, r3, 2 mtspr ctr, r6 ! ctr = r3 / 4 1: lwz r7, 0(r4) @@ -19,6 +17,6 @@ stw r8, 0(r5) addi r4, r4, 4 addi r5, r5, 4 - bc DNZ, 0, 1b ! loop ctr times + bdnz 1b ! loop ctr times add sp, sp, r3 - bclr ALWAYS, 0, 0 + blr diff --git a/mach/powerpc/libem/zer.s b/mach/powerpc/libem/zer.s index 697a5715f..a47a150cc 100644 --- a/mach/powerpc/libem/zer.s +++ b/mach/powerpc/libem/zer.s @@ -1,5 +1,3 @@ -#include "powerpc.h" - .sect .text ! Create empty set. @@ -10,8 +8,8 @@ lwz r3, 0(sp) addi sp, sp, 4 - rlwinm r7, r3, 30, 2, 31 - addi r4, r0, 0 ! r4 = zero + srwi r7, r3, 2 + li r4, 0 ! r4 = zero neg r5, r3 add sp, sp, r5 ! allocate set mr r6, sp ! r6 = ptr to set @@ -19,5 +17,5 @@ 1: stw r4, 0(r6) ! store zero in set addi r6, r6, 4 - bc DNZ, 0, 1b ! loop ctr times - bclr ALWAYS, 0, 0 + bdnz 1b ! loop ctr times + blr diff --git a/mach/powerpc/ncg/table b/mach/powerpc/ncg/table index 1fc1f5b19..7cc4bbbca 100644 --- a/mach/powerpc/ncg/table +++ b/mach/powerpc/ncg/table @@ -10,7 +10,7 @@ INT64 = 8 FP_OFFSET = 0 /* Offset of saved FP relative to our FP */ PC_OFFSET = 4 /* Offset of saved PC relative to our FP */ -#define COMMENT(n) /* comment {LABEL, n} */ +#define COMMENT(n) comment {LABEL, n} #define nicesize(x) ((x)==INT8 || (x)==INT16 || (x)==INT32 || (x)==INT64) @@ -27,24 +27,15 @@ PC_OFFSET = 4 /* Offset of saved PC relative to our FP */ #define los(n) (lo(n) | (((0-(lo(n)>>15)) & ~0xFFFF))) #define his(n) ((hi(n) + (lo(n)>>15)) & 0xFFFF) -#define IFFALSE {CONST, 4} -#define IFTRUE {CONST, 12} -#define ALWAYS {CONST, 20} -#define DCTRZ {CONST, 34} - -#define LT {CONST, 0} -#define GT {CONST, 1} -#define EQ {CONST, 2} - PROPERTIES GPR /* any GPR */ REG /* any allocatable GPR */ - REG_PAIR /* speed hack for sti 8 */ - FPR /* any FPR */ - FREG /* any allocatable FPR */ + REG_PAIR(8) /* speed hack for sti 8 */ + FPR(8) /* any FPR */ + FREG(8) /* any allocatable FPR */ FSREG /* any allocatable single-precision FPR */ SPR /* any SPR */ CR /* any CR */ @@ -54,12 +45,10 @@ PROPERTIES GPR16 GPR17 GPR18 GPR19 GPR20 GPR21 GPR22 GPR23 GPR24 GPR25 GPR26 GPR27 GPR28 GPR29 GPR30 GPR31 - CR0 CR1 - - FPR0 FPR1 FPR2 FPR3 FPR4 FPR5 FPR6 FPR7 - FPR8 FPR9 FPR10 FPR11 FPR12 FPR13 FPR14 FPR15 - FPR16 FPR17 FPR18 FPR19 FPR20 FPR21 FPR22 FPR23 - FPR24 FPR25 FPR26 FPR27 FPR28 FPR29 FPR30 FPR31 + FPR0(8) FPR1(8) FPR2(8) FPR3(8) FPR4(8) FPR5(8) FPR6(8) FPR7(8) + FPR8(8) FPR9(8) FPR10(8) FPR11(8) FPR12(8) FPR13(8) FPR14(8) FPR15(8) + FPR16(8) FPR17(8) FPR18(8) FPR19(8) FPR20(8) FPR21(8) FPR22(8) FPR23(8) + FPR24(8) FPR25(8) FPR26(8) FPR27(8) FPR28(8) FPR29(8) FPR30(8) FPR31(8) REGISTERS @@ -85,7 +74,7 @@ REGISTERS R14("r14") : GPR, REG, GPR14 regvar. R13("r13") : GPR, REG, GPR13 regvar. R12("r12") : GPR, REG, GPR12. - R11("r11") : GPR, GPR11. + R11("r11") : GPR, REG, GPR11. R10("r10") : GPR, REG, GPR10. R9("r9") : GPR, REG, GPR9. R8("r8") : GPR, REG, GPR8. @@ -158,9 +147,9 @@ REGISTERS LR("lr") : SPR. CTR("ctr") : SPR. - C0("cr0") : CR, CR0. + CR0("cr0") : CR. -#define RSCRATCH R11 +#define RSCRATCH R0 #define FSCRATCH F0 @@ -200,13 +189,6 @@ TOKENS SUM_RC = { GPR reg; INT off; } 4. SUM_RR = { GPR reg1; GPR reg2; } 4. - TRISTATE_RC_S = { GPR reg; INT val; } 4. - TRISTATE_RC_U = { GPR reg; INT val; } 4. - TRISTATE_RR_S = { GPR reg1; GPR reg2; } 4. - TRISTATE_RR_U = { GPR reg1; GPR reg2; } 4. - - TRISTATE_FF = { FPR reg1; FPR reg2; } 4. - SEX_B = { GPR reg; } 4. SEX_H = { GPR reg; } 4. @@ -231,6 +213,20 @@ TOKENS XOR_RIS = { GPR reg; INT valhi; } 4. XOR_RC = { GPR reg; INT val; } 4. + COND_RC = { GPR reg; INT val; } 4. + COND_RR = { GPR reg1; GPR reg2; } 4. + CONDL_RC = { GPR reg; INT val; } 4. + CONDL_RR = { GPR reg1; GPR reg2; } 4. + COND_FS = { FSREG reg1; FSREG reg2; } 4. + COND_FD = { FREG reg1; FREG reg2; } 4. + + XEQ = { GPR reg; } 4. + XNE = { GPR reg; } 4. + XGT = { GPR reg; } 4. + XGE = { GPR reg; } 4. + XLT = { GPR reg; } 4. + XLE = { GPR reg; } 4. + SETS @@ -246,9 +242,6 @@ SETS SUM_ALL = SUM_RC + SUM_RR. - TRISTATE_ALL = TRISTATE_RC_S + TRISTATE_RC_U + TRISTATE_RR_S + - TRISTATE_RR_U + TRISTATE_FF. - SEX_ALL = SEX_B + SEX_H. LOGICAL_ALL = NOT_R + AND_RR + OR_RR + OR_RC + XOR_RR + @@ -265,8 +258,7 @@ SETS /* anything killed by sti (store indirect) */ MEMORY = IND_ALL_BHW + IND_ALL_D. - OP_ALL_W = SUM_ALL + TRISTATE_ALL + SEX_ALL + LOGICAL_ALL + - IND_ALL_W. + OP_ALL_W = SUM_ALL + SEX_ALL + LOGICAL_ALL + IND_ALL_W. INSTRUCTIONS @@ -293,14 +285,27 @@ INSTRUCTIONS andisX "andis." GPR:wo:cc, GPR:ro, CONST:ro. b LABEL:ro. bc CONST:ro, CONST:ro, LABEL:ro. + beq LABEL:ro. + bne LABEL:ro. + bgt LABEL:ro. + bge LABEL:ro. + blt LABEL:ro. + ble LABEL:ro. + bxx LABEL:ro. /* dummy */ bcctr CONST:ro, CONST:ro, CONST:ro. + bctr. bcctrl CONST:ro, CONST:ro, CONST:ro. + bctrl. bclr CONST:ro, CONST:ro, CONST:ro. bl LABEL:ro. cmp CR:ro, CONST:ro, GPR:ro, GPR:ro kills :cc. + cmpw GPR:ro, GPR:ro kills :cc. cmpi CR:ro, CONST:ro, GPR:ro, CONST:ro kills :cc. + cmpwi GPR:ro, CONST:ro kills :cc. cmpl CR:ro, CONST:ro, GPR:ro, GPR:ro kills :cc. + cmplw GPR:ro, GPR:ro kills :cc. cmpli CR:ro, CONST:ro, GPR:ro, CONST:ro kills :cc. + cmplwi GPR:ro, CONST:ro kills :cc. divw GPR:wo, GPR:ro, GPR:ro cost(4, 23). divwu GPR:wo, GPR:ro, GPR:ro cost(4, 23). eqv GPR:wo, GPR:ro, GPR:ro. @@ -308,7 +313,8 @@ INSTRUCTIONS extsh GPR:wo, GPR:ro. fadd FREG:wo, FREG:ro, FREG:ro cost(4, 5). fadds FSREG:wo, FSREG:ro, FSREG:ro cost(4, 5). - fcmpo CR:wo, FPR:ro, FPR:ro cost(4, 5). + fcmpo CR:wo, FREG:ro, FREG:ro cost(4, 5). + fcmpo CR:wo, FSREG:ro, FSREG:ro cost(4, 5). fdiv FREG:wo, FREG:ro, FREG:ro cost(4, 35). fdivs FSREG:wo, FSREG:ro, FSREG:ro cost(4, 21). fmr FPR:wo, FPR:ro cost(4, 5). @@ -349,6 +355,8 @@ INSTRUCTIONS oris GPR:wo, GPR:ro, CONST:ro. orX "or." GPR:wo:cc, GPR:ro, GPR:ro. rlwinm GPR:wo, GPR:ro, CONST:ro, CONST:ro, CONST:ro. + extlwi GPR:wo, GPR:ro, CONST:ro, CONST:ro. + extrwi GPR:wo, GPR:ro, CONST:ro, CONST:ro. slw GPR:wo, GPR:ro, GPR:ro. subf GPR:wo, GPR:ro, GPR:ro. sraw GPR:wo, GPR:ro, GPR:ro cost(4, 2). @@ -566,67 +574,6 @@ MOVES COMMENT("move FPR->IND_RR_W") stfdx %1, %2.reg1, %2.reg2 -/* Extract condition code field (actually produces (CC&3)<<2) */ - - from CR0 to GPR - gen - COMMENT("move CR0->GPR") - mfcr %2 - rlwinm %2, %2, {CONST, 4}, {CONST, 32-4}, {CONST, 31-2} - -/* Comparisons */ - - from TRISTATE_RR_S to CR0 - gen - cmp %2, {CONST, 0}, %1.reg1, %1.reg2 - - from TRISTATE_RR_U to CR0 - gen - cmpl %2, {CONST, 0}, %1.reg1, %1.reg2 - - from TRISTATE_RC_S to CR0 - gen - COMMENT("move TRISTATE_RC_S->CR0 large") - move {CONST, %1.val}, RSCRATCH - cmp %2, {CONST, 0}, %1.reg, RSCRATCH - - from TRISTATE_RC_U smallu(%val) to CR0 - gen - COMMENT("move TRISTATE_RC_U->CR0 small") - cmpli %2, {CONST, 0}, %1.reg, {CONST, %1.val} - - from TRISTATE_RC_U to CR0 - gen - COMMENT("move TRISTATE_RC_U->CR0") - move {CONST, %1.val}, RSCRATCH - cmpl %2, {CONST, 0}, %1.reg, RSCRATCH - - from TRISTATE_FF to CR0 - gen - COMMENT("move TRISTATE_FF->CR0") - fcmpo %2, %1.reg1, %1.reg2 - - from GPR to CR0 - gen - COMMENT("move GPR->CR0") - orX RSCRATCH, %1, %1 /* alas, can't call test */ - - from TRISTATE_RR_S + TRISTATE_RC_S + TRISTATE_FF to GPR - gen - COMMENT("move TRISTATE_R*_S->GPR") - move %1, C0 - move C0, RSCRATCH - move {LABEL, ".tristate_s_table"}, %2 - lwzx %2, %2, RSCRATCH - - from TRISTATE_RR_U + TRISTATE_RC_U to GPR - gen - COMMENT("move TRISTATE_R*_U->GPR") - move %1, C0 - move C0, RSCRATCH - move {LABEL, ".tristate_u_table"}, %2 - lwzx %2, %2, RSCRATCH - /* Logicals */ from NOT_R to GPR @@ -669,6 +616,71 @@ MOVES COMMENT("move XOR_RC->GPR") xori %2, %1.reg, {CONST, %1.val} +/* Conditions */ + + /* Compare values, then copy cr0 to GPR. */ + + from COND_RC to GPR + gen + cmpwi %1.reg, {CONST, %1.val} + mfcr %2 + + from COND_RR to GPR + gen + cmpw %1.reg1, %1.reg2 + mfcr %2 + + from CONDL_RC to GPR + gen + cmplwi %1.reg, {CONST, %1.val} + mfcr %2 + + from CONDL_RR to GPR + gen + cmplw %1.reg1, %1.reg2 + mfcr %2 + + from COND_FS to GPR + gen + fcmpo CR0, %1.reg1, %1.reg2 + mfcr %2 + + from COND_FD to GPR + gen + fcmpo CR0, %1.reg1, %1.reg2 + mfcr %2 + + /* Given a copy of cr0 in %1.reg, extract a condition bit + * (lt, gt, eq) and perhaps flip it. + */ + + from XEQ to GPR + gen + extrwi %2, %1.reg, {CONST, 1}, {CONST, 2} + + from XNE to GPR + gen + extrwi %2, %1.reg, {CONST, 1}, {CONST, 2} + xori %2, %2, {CONST, 1} + + from XGT to GPR + gen + extrwi %2, %1.reg, {CONST, 1}, {CONST, 1} + + from XGE to GPR + gen + extrwi %2, %1.reg, {CONST, 1}, {CONST, 0} + xori %2, %2, {CONST, 1} + + from XLT to GPR + gen + extrwi %2, %1.reg, {CONST, 1}, {CONST, 0} + + from XLE to GPR + gen + extrwi %2, %1.reg, {CONST, 1}, {CONST, 1} + xori %2, %2, {CONST, 1} + /* Miscellaneous */ from OP_ALL_W + LABEL + CONST_ALL to GPRE @@ -720,9 +732,9 @@ STACKINGRULES extsh RSCRATCH, %1.reg stwu RSCRATCH, {GPRINDIRECT, SP, 0-4} - from SUM_ALL + TRISTATE_ALL + LOGICAL_ALL to STACK + from SUM_ALL + LOGICAL_ALL to STACK gen - COMMENT("stack SUM_ALL + TRISTATE_ALL + LOGICAL_ALL") + COMMENT("stack SUM_ALL + LOGICAL_ALL") move %1, RSCRATCH stwu RSCRATCH, {GPRINDIRECT, SP, 0-4} @@ -804,7 +816,7 @@ COERCIONS extsh %a, %1.reg yields %a - from SUM_ALL + TRISTATE_ALL + LOGICAL_ALL + from SUM_ALL + LOGICAL_ALL uses REG gen move %1, %a @@ -1683,153 +1695,337 @@ PATTERNS cal ".inn" + /* Boolean resolutions */ pat teq /* top = (top == 0) */ - with TRISTATE_ALL + GPR + with REG uses reusing %1, REG gen - move %1, C0 - move C0, RSCRATCH - move {LABEL, ".teq_table"}, %a - lwzx %a, %a, RSCRATCH + test %1 + mfcr %a + move {XEQ, %a}, %a yields %a pat tne /* top = (top != 0) */ - with TRISTATE_ALL + GPR + with REG uses reusing %1, REG gen - move %1, C0 - move C0, RSCRATCH - move {LABEL, ".tne_table"}, %a - lwzx %a, %a, RSCRATCH + test %1 + mfcr %a + move {XNE, %a}, %a yields %a pat tlt /* top = (top < 0) */ - with TRISTATE_ALL + GPR + with REG uses reusing %1, REG gen - move %1, C0 - move C0, RSCRATCH - move {LABEL, ".tlt_table"}, %a - lwzx %a, %a, RSCRATCH + test %1 + mfcr %a + move {XLT, %a}, %a yields %a pat tle /* top = (top <= 0) */ - with TRISTATE_ALL + GPR + with REG uses reusing %1, REG gen - move %1, C0 - move C0, RSCRATCH - move {LABEL, ".tle_table"}, %a - lwzx %a, %a, RSCRATCH + test %1 + mfcr %a + move {XLE, %a}, %a yields %a pat tgt /* top = (top > 0) */ - with TRISTATE_ALL + GPR + with REG uses reusing %1, REG gen - move %1, C0 - move C0, RSCRATCH - move {LABEL, ".tgt_table"}, %a - lwzx %a, %a, RSCRATCH + test %1 + mfcr %a + move {XGT, %a}, %a yields %a pat tge /* top = (top >= 0) */ - with TRISTATE_ALL + GPR + with REG uses reusing %1, REG gen - move %1, C0 - move C0, RSCRATCH - move {LABEL, ".tge_table"}, %a - lwzx %a, %a, RSCRATCH + test %1 + mfcr %a + move {XGE, %a}, %a yields %a + pat cmi teq $1==4 /* Signed second == top */ + with REG CONST2 + uses reusing %1, REG={COND_RC, %1, %2.val} + gen move {XEQ, %a}, %a + yields %a + with CONST2 REG + uses reusing %1, REG={COND_RC, %2, %1.val} + gen move {XEQ, %a}, %a + yields %a + with REG REG + uses reusing %1, REG={COND_RR, %2, %1} + gen move {XEQ, %a}, %a + yields %a + pat cmi tne $1==4 /* Signed second != top */ + with REG CONST2 + uses reusing %1, REG={COND_RC, %1, %2.val} + gen move {XNE, %a}, %a + yields %a + with CONST2 REG + uses reusing %1, REG={COND_RC, %2, %1.val} + gen move {XNE, %a}, %a + yields %a + with REG REG + uses reusing %1, REG={COND_RR, %2, %1} + gen move {XNE, %a}, %a + yields %a + pat cmi tgt $1==4 /* Signed second > top */ + with REG CONST2 + uses reusing %1, REG={COND_RC, %1, %2.val} + gen move {XLT, %a}, %a + yields %a + with CONST2 REG + uses reusing %1, REG={COND_RC, %2, %1.val} + gen move {XGT, %a}, %a + yields %a + with REG REG + uses reusing %1, REG={COND_RR, %2, %1} + gen move {XGT, %a}, %a + yields %a -/* Simple branches */ + pat cmi tge $1==4 /* Signed second >= top */ + with REG CONST2 + uses reusing %1, REG={COND_RC, %1, %2.val} + gen move {XLE, %a}, %a + yields %a + with CONST2 REG + uses reusing %1, REG={COND_RC, %2, %1.val} + gen move {XGE, %a}, %a + yields %a + with REG REG + uses reusing %1, REG={COND_RR, %2, %1} + gen move {XGE, %a}, %a + yields %a - pat zeq /* Branch if signed top == 0 */ - with TRISTATE_ALL+GPR STACK - gen - move %1, C0 - bc IFTRUE, EQ, {LABEL, $1} + pat cmi tlt $1==4 /* Signed second < top */ + with REG CONST2 + uses reusing %1, REG={COND_RC, %1, %2.val} + gen move {XGT, %a}, %a + yields %a + with CONST2 REG + uses reusing %1, REG={COND_RC, %2, %1.val} + gen move {XLT, %a}, %a + yields %a + with REG REG + uses reusing %1, REG={COND_RR, %2, %1} + gen move {XLT, %a}, %a + yields %a - pat beq - leaving - cmi INT32 - zeq $1 + pat cmi tle $1==4 /* Signed second <= top */ + with REG CONST2 + uses reusing %1, REG={COND_RC, %1, %2.val} + gen move {XGE, %a}, %a + yields %a + with CONST2 REG + uses reusing %1, REG={COND_RC, %2, %1.val} + gen move {XLE, %a}, %a + yields %a + with REG REG + uses reusing %1, REG={COND_RR, %2, %1} + gen move {XLE, %a}, %a + yields %a - pat zne /* Branch if signed top != 0 */ - with TRISTATE_ALL+GPR STACK - gen - move %1, C0 - bc IFFALSE, EQ, {LABEL, $1} + pat cmu teq $1==4 /* Unsigned second == top */ + with REG UCONST2 + uses reusing %1, REG={CONDL_RC, %1, %2.val} + gen move {XEQ, %a}, %a + yields %a + with UCONST2 REG + uses reusing %1, REG={CONDL_RC, %2, %1.val} + gen move {XEQ, %a}, %a + yields %a + with REG REG + uses reusing %1, REG={CONDL_RR, %2, %1} + gen move {XEQ, %a}, %a + yields %a - pat bne - leaving - cmi INT32 - zne $1 + pat cmu tne $1==4 /* Unsigned second != top */ + with REG UCONST2 + uses reusing %1, REG={CONDL_RC, %1, %2.val} + gen move {XNE, %a}, %a + yields %a + with UCONST2 REG + uses reusing %1, REG={CONDL_RC, %2, %1.val} + gen move {XNE, %a}, %a + yields %a + with REG REG + uses reusing %1, REG={CONDL_RR, %2, %1} + gen move {XNE, %a}, %a + yields %a - pat zgt /* Branch if signed top > 0 */ - with TRISTATE_ALL+GPR STACK - gen - move %1, C0 - bc IFTRUE, GT, {LABEL, $1} + pat cmu tgt $1==4 /* Unsigned second > top */ + with REG UCONST2 + uses reusing %1, REG={CONDL_RC, %1, %2.val} + gen move {XLT, %a}, %a + yields %a + with UCONST2 REG + uses reusing %1, REG={CONDL_RC, %2, %1.val} + gen move {XGT, %a}, %a + yields %a + with REG REG + uses reusing %1, REG={CONDL_RR, %2, %1} + gen move {XGT, %a}, %a + yields %a - pat bgt - leaving - cmi INT32 - zgt $1 + pat cmu tge $1==4 /* Unsigned second >= top */ + with REG UCONST2 + uses reusing %1, REG={CONDL_RC, %1, %2.val} + gen move {XLE, %a}, %a + yields %a + with UCONST2 REG + uses reusing %1, REG={CONDL_RC, %2, %1.val} + gen move {XGE, %a}, %a + yields %a + with REG REG + uses reusing %1, REG={CONDL_RR, %2, %1} + gen move {XGE, %a}, %a + yields %a - pat zge /* Branch if signed top >= 0 */ - with TRISTATE_ALL+GPR STACK + pat cmu tlt $1==4 /* Unsigned second < top */ + with REG UCONST2 + uses reusing %1, REG={CONDL_RC, %1, %2.val} + gen move {XGT, %a}, %a + yields %a + with UCONST2 REG + uses reusing %1, REG={CONDL_RC, %2, %1.val} + gen move {XLT, %a}, %a + yields %a + with REG REG + uses reusing %1, REG={CONDL_RR, %2, %1} + gen move {XLT, %a}, %a + yields %a + + pat cmu tle $1==4 /* Unsigned second <= top */ + with REG UCONST2 + uses reusing %1, REG={CONDL_RC, %1, %2.val} + gen move {XGE, %a}, %a + yields %a + with UCONST2 REG + uses reusing %1, REG={CONDL_RC, %2, %1.val} + gen move {XLE, %a}, %a + yields %a + with REG REG + uses reusing %1, REG={CONDL_RR, %2, %1} + gen move {XLE, %a}, %a + yields %a + + + +/* Simple branches */ + + proc zxx example zeq + with REG STACK gen - move %1, C0 - bc IFFALSE, LT, {LABEL, $1} + test %1 + bxx* {LABEL, $1} - pat bge - leaving - cmi INT32 - zge $1 + /* Pop signed int, branch if... */ + pat zeq call zxx("beq") /* top == 0 */ + pat zne call zxx("bne") /* top != 0 */ + pat zgt call zxx("bgt") /* top > 0 */ + pat zge call zxx("bge") /* top >= 0 */ + pat zlt call zxx("blt") /* top < 0 */ + pat zle call zxx("ble") /* top >= 0 */ + + /* The peephole optimizer rewrites + * cmi 4 zeq + * as beq, and does same for bne, bgt, and so on. + */ - pat zlt /* Branch if signed top < 0 */ - with TRISTATE_ALL+GPR STACK + proc bxx example beq + with REG CONST2 STACK + gen + cmpwi %1, {CONST, %2.val} + bxx[2] {LABEL, $1} + with CONST2 REG STACK gen - move %1, C0 - bc IFTRUE, LT, {LABEL, $1} + cmpwi %2, {CONST, %1.val} + bxx[1] {LABEL, $1} + with REG REG STACK + gen + cmpw %2, %1 + bxx[1] {LABEL, $1} - pat blt - leaving - cmi INT32 - zlt $1 + /* Pop two signed ints, branch if... */ + pat beq call bxx("beq", "beq") /* second == top */ + pat bne call bxx("bne", "bne") /* second != top */ + pat bgt call bxx("bgt", "blt") /* second > top */ + pat bge call bxx("bge", "ble") /* second >= top */ + pat blt call bxx("blt", "bgt") /* second < top */ + pat ble call bxx("ble", "bge") /* second >= top */ - pat zle /* Branch if signed top >= 0 */ - with TRISTATE_ALL+GPR STACK + proc cmu4zxx example cmu zeq + with REG CONST2 STACK gen - move %1, C0 - bc IFFALSE, GT, {LABEL, $1} + cmplwi %1, {CONST, %2.val} + bxx[2] {LABEL, $2} + with CONST2 REG STACK + gen + cmplwi %2, {CONST, %1.val} + bxx[1] {LABEL, $2} + with REG REG STACK + gen + cmplw %2, %1 + bxx[1] {LABEL, $2} - pat ble - leaving - cmi INT32 - zle $1 + /* Pop two unsigned ints, branch if... */ + pat cmu zeq $1==4 call cmu4zxx("beq", "beq") + pat cmu zne $1==4 call cmu4zxx("bne", "bne") + pat cmu zgt $1==4 call cmu4zxx("bgt", "blt") + pat cmu zge $1==4 call cmu4zxx("bge", "ble") + pat cmu zlt $1==4 call cmu4zxx("blt", "bgt") + pat cmu zle $1==4 call cmu4zxx("ble", "bge") -/* Compare and jump */ + +/* Comparisons */ + + /* Each comparison extracts the lt and gt bits from cr0. + * extlwi %a, %a, 2, 0 + * puts lt in the sign bit, so lt yields a negative result, + * gt yields positive. + * rlwinm %a, %a, 1, 31, 0 + * puts gt in the sign bit, to reverse the comparison. + */ pat cmi $1==INT32 /* Signed tristate compare */ - with CONST_ALL GPR - yields {TRISTATE_RC_S, %2, %1.val} - with GPR GPR - yields {TRISTATE_RR_S, %2, %1} + with REG CONST2 + uses reusing %1, REG={COND_RC, %1, %2.val} + gen rlwinm %a, %a, {CONST, 1}, {CONST, 31}, {CONST, 0} + yields %a + with CONST2 REG + uses reusing %2, REG={COND_RC, %2, %1.val} + gen extlwi %a, %a, {CONST, 2}, {CONST, 0} + yields %a + with REG REG + uses reusing %1, REG={COND_RR, %2, %1} + gen extlwi %a, %a, {CONST, 2}, {CONST, 0} + yields %a pat cmu $1==INT32 /* Unsigned tristate compare */ - with CONST_ALL GPR - yields {TRISTATE_RC_U, %2, %1.val} - with GPR GPR - yields {TRISTATE_RR_U, %2, %1} + with REG UCONST2 + uses reusing %1, REG={CONDL_RC, %1, %2.val} + gen rlwinm %a, %a, {CONST, 1}, {CONST, 31}, {CONST, 0} + yields %a + with UCONST2 REG + uses reusing %2, REG={CONDL_RC, %2, %1.val} + gen extlwi %a, %a, {CONST, 2}, {CONST, 0} + yields %a + with REG REG + uses reusing %1, REG={CONDL_RR, %2, %1} + gen extlwi %a, %a, {CONST, 2}, {CONST, 0} + yields %a pat cmp /* Compare pointers */ leaving @@ -1852,12 +2048,14 @@ PATTERNS /* Other branching and labelling */ pat lab topeltsize($1)==4 && !fallthrough($1) + kills ALL gen labeldef $1 yields R3 pat lab topeltsize($1)==4 && fallthrough($1) - with GPR3 + with GPR3 STACK + kills ALL gen labeldef $1 yields %1 @@ -1893,7 +2091,7 @@ PATTERNS kills ALL gen mtspr CTR, %1 - bcctrl ALWAYS, {CONST, 0}, {CONST, 0} + bctrl. pat lfr $1==INT32 /* Load function result, word */ yields R3 @@ -2020,7 +2218,7 @@ PATTERNS move {IND_RC_W, %a, 4}, SP move {IND_RC_W, %a, 0}, %a mtspr CTR, %a - bcctr ALWAYS, {CONST, 0}, {CONST, 0} + bctr. pat lor $1==0 /* Load FP */ uses REG @@ -2073,12 +2271,11 @@ PATTERNS pat lae rck $2==4 /* Range check */ with REG - uses CR0 gen - cmpli %a, {CONST, 0}, %1, {CONST, rom($1, 1)} - bc IFTRUE, LT, {LABEL, ".trap_erange"} - cmpli %a, {CONST, 0}, %1, {CONST, rom($1, 2)} - bc IFTRUE, GT, {LABEL, ".trap_erange"} + cmpwi %1, {CONST, rom($1, 1)} + blt {LABEL, ".trap_erange"} + cmpwi %1, {CONST, rom($1, 2)} + bgt {LABEL, ".trap_erange"} yields %1 @@ -2132,7 +2329,60 @@ PATTERNS pat cmf $1==INT32 /* Compare single */ with FSREG FSREG - yields {TRISTATE_FF, %2.1, %1.1} + uses REG={COND_FS, %2, %1} + gen extlwi %a, %a, {CONST, 2}, {CONST, 0} + yields %a + + pat cmf teq $1==4 /* Single second == top */ + with FSREG FSREG + uses REG={COND_FS, %2, %1} + gen move {XEQ, %a}, %a + yields %a + + pat cmf tne $1==4 /* Single second == top */ + with FSREG FSREG + uses REG={COND_FS, %2, %1} + gen move {XNE, %a}, %a + yields %a + + pat cmf tgt $1==4 /* Single second > top */ + with FSREG FSREG + uses REG={COND_FS, %2, %1} + gen move {XGT, %a}, %a + yields %a + + pat cmf tge $1==4 /* Single second >= top */ + with FSREG FSREG + uses REG={COND_FS, %2, %1} + gen move {XGE, %a}, %a + yields %a + + pat cmf tlt $1==4 /* Single second < top */ + with FSREG FSREG + uses REG={COND_FS, %2, %1} + gen move {XLT, %a}, %a + yields %a + + pat cmf tle $1==4 /* Single second <= top */ + with FSREG FSREG + uses REG={COND_FS, %2, %1} + gen move {XLE, %a}, %a + yields %a + + proc cmf4zxx example cmf zeq + with FREG FREG STACK + uses REG + gen + fcmpo CR0, %2, %1 + bxx* {LABEL, $2} + + /* Pop 2 singles, branch if... */ + pat cmf zeq $1==4 call cmf4zxx("beq") + pat cmf zne $1==4 call cmf4zxx("bne") + pat cmf zgt $1==4 call cmf4zxx("bgt") + pat cmf zge $1==4 call cmf4zxx("bge") + pat cmf zlt $1==4 call cmf4zxx("blt") + pat cmf zle $1==4 call cmf4zxx("ble") pat loc loc cff $1==INT32 && $2==INT64 /* Convert single to double */ with FSREG @@ -2206,7 +2456,60 @@ PATTERNS pat cmf $1==INT64 /* Compare double */ with FREG FREG - yields {TRISTATE_FF, %2, %1} + uses REG={COND_FD, %2, %1} + gen extlwi %a, %a, {CONST, 2}, {CONST, 0} + yields %a + + pat cmf teq $1==8 /* Double second == top */ + with FREG FREG + uses REG={COND_FD, %2, %1} + gen move {XEQ, %a}, %a + yields %a + + pat cmf tne $1==8 /* Single second == top */ + with FREG FREG + uses REG={COND_FD, %2, %1} + gen move {XNE, %a}, %a + yields %a + + pat cmf tgt $1==8 /* Double second > top */ + with FREG FREG + uses REG={COND_FD, %2, %1} + gen move {XGT, %a}, %a + yields %a + + pat cmf tge $1==8 /* Double second >= top */ + with FREG FREG + uses REG={COND_FD, %2, %1} + gen move {XGE, %a}, %a + yields %a + + pat cmf tlt $1==8 /* Double second < top */ + with FREG FREG + uses REG={COND_FD, %2, %1} + gen move {XLT, %a}, %a + yields %a + + pat cmf tle $1==8 /* Double second <= top */ + with FREG FREG + uses REG={COND_FD, %2, %1} + gen move {XLE, %a}, %a + yields %a + + proc cmf8zxx example cmf zeq + with FREG FREG STACK + uses REG + gen + fcmpo CR0, %2, %1 + bxx* {LABEL, $2} + + /* Pop 2 doubles, branch if... */ + pat cmf zeq $1==8 call cmf8zxx("beq") + pat cmf zne $1==8 call cmf8zxx("bne") + pat cmf zgt $1==8 call cmf8zxx("bgt") + pat cmf zge $1==8 call cmf8zxx("bge") + pat cmf zlt $1==8 call cmf8zxx("blt") + pat cmf zle $1==8 call cmf8zxx("ble") pat loc loc cff $1==INT64 && $2==INT32 /* Convert double to single */ with FREG @@ -2238,14 +2541,14 @@ PATTERNS pat fef $1==INT64 /* Split exponent, fraction */ with GPR3 GPR4 - kills FPR0, FPR1, GPR6, GPR7 + kills ALL gen bl {LABEL, ".fef8"} yields R4 R3 R5 pat fif $1==INT64 /* Multiply then split integer, fraction */ with FPR1 FPR2 - kills FPR1, FPR2, GPR3, GPR4, GPR5, GPR6 + kills ALL gen bl {LABEL, ".fif8"} yields F1 F2 diff --git a/mach/powerpc/top/table b/mach/powerpc/top/table index acbe543a7..fdec03b2e 100644 --- a/mach/powerpc/top/table +++ b/mach/powerpc/top/table @@ -6,15 +6,15 @@ LABEL_STARTER '.'; %%; -P, Q, R { TRUE }; +RNZ { strcmp(VAL, "r0") }; /* not r0 */ X, Y, Z { TRUE }; %%; /* Whitespace is significant here! */ -addi X, X, 0 -> ; -addis X, X, 0 -> ; +addi RNZ, RNZ, 0 -> ; +addis RNZ, RNZ, 0 -> ; mr X, X -> ; fmr X, X -> ; diff --git a/plat/linux/libsys/sigprocmask.c b/plat/linux/libsys/sigprocmask.c new file mode 100644 index 000000000..ad1b339c2 --- /dev/null +++ b/plat/linux/libsys/sigprocmask.c @@ -0,0 +1,7 @@ +#include +#include "libsys.h" + +int sigprocmask(int flags, const sigset_t *new, sigset_t *old) +{ + return _syscall(__NR_sigprocmask, flags, (quad) new, (quad) old); +} diff --git a/plat/linux386/include/unistd.h b/plat/linux386/include/unistd.h index 5c6f31ef4..8c8637c09 100644 --- a/plat/linux386/include/unistd.h +++ b/plat/linux386/include/unistd.h @@ -56,7 +56,6 @@ extern int write(int fd, void* buffer, size_t count); extern off_t lseek(int fildes, off_t offset, int whence); extern int fcntl(int fd, int op, ...); extern int unlink(const char* path); -extern int remove(const char* path); /* Special variables */ @@ -117,8 +116,16 @@ typedef int sig_atomic_t; #define _NSIG 32 /* Biggest signal number + 1 (not including real-time signals). */ + +/* sigprocmask */ +#define SIG_BLOCK 0 +#define SIG_UNBLOCK 1 +#define SIG_SETMASK 2 +typedef unsigned long sigset_t; + typedef void (*sighandler_t)(int); extern sighandler_t signal(int signum, sighandler_t handler); +extern int sigprocmask(int, const sigset_t *, sigset_t *); extern int raise(int signum); diff --git a/plat/linux68k/include/unistd.h b/plat/linux68k/include/unistd.h index 307192f77..927a20459 100644 --- a/plat/linux68k/include/unistd.h +++ b/plat/linux68k/include/unistd.h @@ -55,6 +55,7 @@ extern int read(int fd, void* buffer, size_t count); extern int write(int fd, void* buffer, size_t count); extern off_t lseek(int fildes, off_t offset, int whence); extern int fcntl(int fd, int op, ...); +extern int unlink(const char* path); /* Special variables */ @@ -67,6 +68,7 @@ extern pid_t getpid(void); extern int brk(void* ptr); extern void* sbrk(int increment); extern int isatty(int d); +extern int execve(const char *path, char *const argv[], char *const envp[]); /* Signal handling */ @@ -114,8 +116,16 @@ typedef int sig_atomic_t; #define _NSIG 32 /* Biggest signal number + 1 (not including real-time signals). */ + +/* sigprocmask */ +#define SIG_BLOCK 0 +#define SIG_UNBLOCK 1 +#define SIG_SETMASK 2 +typedef unsigned long sigset_t; + typedef void (*sighandler_t)(int); extern sighandler_t signal(int signum, sighandler_t handler); +extern int sigprocmask(int, const sigset_t *, sigset_t *); extern int raise(int signum); diff --git a/plat/linuxppc/include/unistd.h b/plat/linuxppc/include/unistd.h index a31bd9f0d..f57705365 100644 --- a/plat/linuxppc/include/unistd.h +++ b/plat/linuxppc/include/unistd.h @@ -55,6 +55,7 @@ extern int read(int fd, void* buffer, size_t count); extern int write(int fd, void* buffer, size_t count); extern off_t lseek(int fildes, off_t offset, int whence); extern int fcntl(int fd, int op, ...); +extern int unlink(const char* path); /* Special variables */ @@ -115,8 +116,34 @@ typedef int sig_atomic_t; #define _NSIG 32 /* Biggest signal number + 1 (not including real-time signals). */ + +/* sigprocmask */ +#define SIG_BLOCK 0 +#define SIG_UNBLOCK 1 +#define SIG_SETMASK 2 +typedef unsigned long sigset_t; + +/* sa_flags */ +#define SA_NODEFER 0x40000000UL +#define SA_RESETHAND 0x80000000UL + +struct __siginfo; +struct sigaction { + union { + void (*__sa_handler)(int); + void (*__sa_sigaction)(int, struct __siginfo *, void *); + } __sigaction_u; + sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer)(void); +}; +#define sa_handler __sigaction_u.__sa_handler +#define sa_sigaction __sigaction_u.__sa_sigaction + typedef void (*sighandler_t)(int); +extern int sigaction(int, const struct sigaction *, struct sigaction *); extern sighandler_t signal(int signum, sighandler_t handler); +extern int sigprocmask(int, const sigset_t *, sigset_t *); extern int raise(int signum); diff --git a/plat/linuxppc/libsys/build.lua b/plat/linuxppc/libsys/build.lua index e74f3f416..f7b16b378 100644 --- a/plat/linuxppc/libsys/build.lua +++ b/plat/linuxppc/libsys/build.lua @@ -1,16 +1,36 @@ acklibrary { - name = "lib", - srcs = { - "./*.s", - "plat/linux/libsys/*.c", - "plat/linux/libsys/*.s", - }, + name = "lib", + srcs = { + "./_syscall.s", + "./sigaction.s", + "./signal.c", + "./trap.s", + "plat/linux/libsys/_exit.c", + "plat/linux/libsys/_hol0.s", + "plat/linux/libsys/close.c", + "plat/linux/libsys/creat.c", + "plat/linux/libsys/errno.s", + "plat/linux/libsys/execve.c", + "plat/linux/libsys/getpid.c", + "plat/linux/libsys/gettimeofday.c", + "plat/linux/libsys/ioctl.c", + "plat/linux/libsys/isatty.c", + "plat/linux/libsys/kill.c", + "plat/linux/libsys/lseek.c", + "plat/linux/libsys/open.c", + "plat/linux/libsys/read.c", + "plat/linux/libsys/sbrk.c", + -- omit signal.c + "plat/linux/libsys/sigprocmask.c", + "plat/linux/libsys/unlink.c", + "plat/linux/libsys/write.c", + }, deps = { "lang/cem/libcc.ansi/headers+headers", "plat/linuxppc/include+headers", }, - vars = { - plat = "linuxppc" - } + vars = { + plat = "linuxppc" + } } diff --git a/plat/linuxppc/libsys/sigaction.s b/plat/linuxppc/libsys/sigaction.s new file mode 100644 index 000000000..0509c8e72 --- /dev/null +++ b/plat/linuxppc/libsys/sigaction.s @@ -0,0 +1,156 @@ +#define __NR_sigaction 67 +#define SIG_BLOCK 0 +#define SIG_SETMASK 2 +#define MAXSIG 32 + +/* offsets into our stack frame */ +#define mynew 16 /* new sigaction */ +#define mynset 32 /* new signal set */ +#define myoset 36 /* old signal set */ +#define mysave 40 +#define mysize 56 + +.sect .text; .sect .rodata; .sect .data; .sect .bss + +/* + * Linux calls signal handlers with arguments in registers, but the + * ACK expects arguments on the stack. This sigaction() uses a + * "bridge" to move the arguments. + */ +.sect .text +.define _sigaction +_sigaction: + mflr r0 + subi r1, r1, mysize + stw r31, mysave+8(r1) + stw r30, mysave+4(r1) + stw r29, mysave(r1) + stw r0, mysave+12(r1) + li r3, 0 + stw r3, mynset(r1) ! mynset = 0 + lwz r29, mysize(r1) ! r29 = signal number + lwz r30, mysize+4(r1) ! r30 = new action + lwz r31, mysize+8(r1) ! r31 = old action + /* + * If the new action is non-NULL, the signal number is in + * range 1 to MAXSIG, and the new handler is not SIG_DFL 0 + * or SIG_IGN 1, then we interpose our bridge. + */ + cmpwi cr0, r30, 0 + subi r7, r29, 1 ! r7 = index in handlers + cmplwi cr7, r7, MAXSIG ! unsigned comparison + beq cr0, kernel + bge cr7, kernel + lwz r3, 0(r30) ! r3 = new handler + clrrwi. r3, r3, 1 + beq cr0, kernel + /* + * Block the signal while we build the bridge. Prevents a + * race if a signal arrives after we change the bridge but + * before we change the action in the kernel. + */ + li r4, 1 + slw r4, r4, r7 + stw r4, mynset(r1) ! mynmask = 1 << (signal - 1) + li r3, SIG_BLOCK + la r4, mynset(r1) + la r5, myoset(r1) + stw r3, 0(r1) + stw r4, 4(r1) + stw r5, 8(r1) + bl _sigprocmask + /* + * Point our bridge to the new signal handler. Then copy the + * new sigaction but point it to our bridge. + */ + lis r6, hi16[handlers] + ori r6, r6, lo16[handlers] + subi r7, r29, 1 + slwi r7, r7, 2 + lwz r3, 0(r30) ! r3 = new handler + stwx r3, r6, r7 ! put it in array of handlers + lis r3, hi16[bridge] + ori r3, r3, lo16[bridge] + lwz r4, 4(r30) + lwz r5, 8(r30) + lwz r6, 12(r30) + stw r3, mynew(r1) ! sa_handler or sa_sigaction + stw r4, mynew+4(r1) ! sa_mask + stw r5, mynew+8(r1) ! sa_flags + stw r6, mynew+12(r1) ! sa_restorer + la r30, mynew(r1) +kernel: + li r3, __NR_sigaction + stw r3, 0(r1) + stw r29, 4(r1) + stw r30, 8(r1) + stw r31, 12(r1) + bl __syscall + /* + * If we blocked the signal, then restore the old signal mask. + */ + lwz r3, mynset(r1) + cmpwi cr0, r3, 0 + beq cr0, fixold + li r3, SIG_SETMASK + la r4, myoset(r1) + li r5, 0 + stw r3, 0(r1) + stw r4, 4(r1) + stw r5, 8(r1) + bl _sigprocmask + /* + * If the old sigaction is non-NULL and points to our bridge, + * then point it to the signal handler. + */ +fixold: + cmpwi cr0, r31, 0 + beq cr0, leave + lis r3, hi16[bridge] + ori r3, r3, lo16[bridge] + lwz r4, 0(r31) + cmpw cr0, r3, r4 + bne cr0, leave + lis r6, hi16[handlers] + ori r6, r6, lo16[handlers] + subi r7, r29, 1 + slwi r7, r7, 2 + lwzx r3, r6, r7 ! get it from array of handlers + stw r3, 0(r31) ! put it in old sigaction +leave: + lwz r0, mysave+12(r1) + lwz r29, mysave(r1) + lwz r30, mysave+4(r1) + lwz r31, mysave+8(r1) + addi r1, r1, mysize + mtlr r0 + blr ! return from sigaction + +/* + * Linux calls bridge(signum) or bridge(signum, info, context) with + * arguments in registers r3, r4, r5. + */ +bridge: + mflr r0 + subi r1, r1, 16 + stw r0, 12(r1) + stw r3, 0(r1) ! signal number + stw r4, 4(r1) ! info + stw r5, 8(r1) ! context + + lis r6, hi16[handlers] + ori r6, r6, lo16[handlers] + subi r7, r3, 1 + slwi r7, r7, 2 + lwzx r6, r6, r7 + mtctr r6 + bctrl ! call our signal handler + + lwz r0, 12(r1) + addi r1, r1, 16 + mtlr r0 + blr ! return from bridge + +.sect .bss +handlers: + .space 4 * MAXSIG ! array of signal handlers diff --git a/plat/linuxppc/libsys/signal.c b/plat/linuxppc/libsys/signal.c new file mode 100644 index 000000000..0ed1918e1 --- /dev/null +++ b/plat/linuxppc/libsys/signal.c @@ -0,0 +1,19 @@ +#include + +/* + * Uses our bridge in sigaction.s when calling the signal handler. + * Mimics Linux __NR_signal by using SA_NODEFER | SA_RESETHAND. + */ +sighandler_t signal(int signum, sighandler_t handler) { + struct sigaction new, old; + int i; + + new.sa_handler = handler; + new.sa_mask = 0; /* empty set */ + new.sa_flags = SA_NODEFER | SA_RESETHAND; + + i = sigaction(signum, &new, &old); + if (i < 0) + return SIG_ERR; + return old.sa_handler; +} diff --git a/util/led/relocate.c b/util/led/relocate.c index 7e2f9db10..036b7dbb8 100644 --- a/util/led/relocate.c +++ b/util/led/relocate.c @@ -107,14 +107,20 @@ static uint32_t get_vc4_valu(char* addr) static bool is_powerpc_memory_op(uint32_t opcode) { - /* Tests for any PowerPC memory indirection instruction where the payload - * is a *signed* 16-bit value. */ + /* Tests for any PowerPC memory indirection instruction (or + * addi) where the payload is a *signed* 16-bit value. */ switch ((opcode & 0xfc000000) >> 26) { + case 14: /* addi */ case 34: /* lbz */ + case 48: /* lfs */ + case 50: /* lfd */ + case 42: /* lha */ case 40: /* lhz */ case 32: /* lwz */ case 38: /* stb */ + case 52: /* stfs */ + case 54: /* stfd */ case 44: /* sth */ case 36: /* stw */ return true;