Merge pull request #49 from kernigh/kernigh-pr-xm

PowerPC extended mnemonics
This commit is contained in:
David Given 2017-01-26 21:21:47 +01:00 committed by GitHub
commit 559233e973
43 changed files with 1490 additions and 655 deletions

View file

@ -31,3 +31,9 @@ typedef uint32_t quad;
#define VALWIDTH 8 #define VALWIDTH 8
#define FIXUPFLAGS (RELBR | RELWR) #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)

View file

@ -8,20 +8,35 @@
%token <y_word> FPR %token <y_word> FPR
%token <y_word> CR %token <y_word> CR
%token <y_word> C %token <y_word> C
%token <y_word> OP_HI OP_HA OP_LO
%token <y_word> OP %token <y_word> OP
%token <y_word> OP_BDA
%token <y_word> OP_BDL
%token <y_word> OP_BF %token <y_word> OP_BF
%token <y_word> OP_BF_BFA %token <y_word> OP_BF_BFA
%token <y_word> OP_BF_FRA_FRB %token <y_word> OP_BF_FRA_FRB
%token <y_word> OP_BF_L_RA_RB %token <y_word> OP_BF_L_RA_RB
%token <y_word> OP_BF_L_RA_SI %token <y_word> OP_BF_L_RA_SI
%token <y_word> OP_BF_L_RA_UI %token <y_word> OP_BF_L_RA_UI
%token <y_word> OP_BF_RA_RB
%token <y_word> OP_BF_RA_SI
%token <y_word> OP_BF_RA_UI
%token <y_word> OP_BF_U_C %token <y_word> OP_BF_U_C
%token <y_word> OP_BH
%token <y_word> OP_BI_BDA
%token <y_word> OP_BI_BDL
%token <y_word> OP_BI_BH
%token <y_word> OP_BICR_BDA
%token <y_word> OP_BICR_BDL
%token <y_word> OP_BICR_BH
%token <y_word> OP_BO_BI_BDA %token <y_word> OP_BO_BI_BDA
%token <y_word> OP_BO_BI_BDL %token <y_word> OP_BO_BI_BDL
%token <y_word> OP_BO_BI_BH %token <y_word> OP_BO_BI_BH
%token <y_word> OP_BT_C %token <y_word> OP_BT_C
%token <y_word> OP_BT_BA_BA
%token <y_word> OP_BT_BA_BB %token <y_word> OP_BT_BA_BB
%token <y_word> OP_BT_BT_BT
%token <y_word> OP_FLM_FRB_C %token <y_word> OP_FLM_FRB_C
%token <y_word> OP_FRS_RA_D %token <y_word> OP_FRS_RA_D
%token <y_word> OP_FRS_RA_RB %token <y_word> OP_FRS_RA_RB
@ -32,16 +47,18 @@
%token <y_word> OP_FRT_FRB_C %token <y_word> OP_FRT_FRB_C
%token <y_word> OP_FRT_RA_D %token <y_word> OP_FRT_RA_D
%token <y_word> OP_FRT_RA_RB %token <y_word> OP_FRT_RA_RB
%token <y_word> OP_L
%token <y_word> OP_LEV %token <y_word> OP_LEV
%token <y_word> OP_LIA %token <y_word> OP_LIA
%token <y_word> OP_LIL %token <y_word> OP_LIL
%token <y_word> OP_L_RB %token <y_word> OP_LI32
%token <y_word> OP_RA_RB %token <y_word> OP_RA_RS_RB_C
%token <y_word> OP_RB %token <y_word> OP_RA_RS_RB_MB5_ME5_C
%token <y_word> OP_RS %token <y_word> OP_RA_RS_RB_MB6_C
%token <y_word> OP_RA_RS_SH5_C
%token <y_word> OP_RA_RS_SH5_MB5_ME5_C
%token <y_word> OP_RA_RS_SH6_C
%token <y_word> OP_RA_RS_SH6_MB6_C
%token <y_word> OP_RS_FXM %token <y_word> OP_RS_FXM
%token <y_word> OP_RS_L
%token <y_word> OP_RS_RA %token <y_word> OP_RS_RA
%token <y_word> OP_RS_RA_C %token <y_word> OP_RS_RA_C
%token <y_word> OP_RS_RA_D %token <y_word> OP_RS_RA_D
@ -50,14 +67,6 @@
%token <y_word> OP_RS_RA_RB %token <y_word> OP_RS_RA_RB
%token <y_word> OP_RS_RA_RB_C %token <y_word> OP_RS_RA_RB_C
%token <y_word> OP_RS_RA_RA_C %token <y_word> OP_RS_RA_RA_C
%token <y_word> OP_RS_RA_RB_MB5_ME5_C
%token <y_word> OP_RS_RA_RB_MB6_C
%token <y_word> OP_RS_RA_RB_ME6_C
%token <y_word> OP_RS_RA_SH_MB5_ME5_C
%token <y_word> OP_RS_RA_SH_MB6_SH_C
%token <y_word> OP_RS_RA_SH_ME6_SH_C
%token <y_word> OP_RS_RA_SH5_C
%token <y_word> OP_RS_RA_SH6_C
%token <y_word> OP_RS_RA_UI %token <y_word> OP_RS_RA_UI
%token <y_word> OP_RS_RA_UI_CC %token <y_word> OP_RS_RA_UI_CC
%token <y_word> OP_RS_RB %token <y_word> OP_RS_RB
@ -73,22 +82,26 @@
%token <y_word> OP_RT_RA_RB_C %token <y_word> OP_RT_RA_RB_C
%token <y_word> OP_RT_RA_SI %token <y_word> OP_RT_RA_SI
%token <y_word> OP_RT_RA_SI_addic %token <y_word> OP_RT_RA_SI_addic
%token <y_word> OP_RT_RA_SI_subi
%token <y_word> OP_RT_RA_SI_subic
%token <y_word> OP_RT_RB %token <y_word> OP_RT_RB
%token <y_word> OP_RT_RB_RA_C
%token <y_word> OP_RT_SI
%token <y_word> OP_RT_SPR %token <y_word> OP_RT_SPR
%token <y_word> OP_RT_SR %token <y_word> OP_RT_SR
%token <y_word> OP_RT_TBR %token <y_word> OP_RT_TBR
%token <y_word> OP_TH_RA_RB %token <y_word> OP_TH_RA_RB
%token <y_word> OP_TO_RA_RB %token <y_word> OP_TO_RA_RB
%token <y_word> OP_TO_RA_SI %token <y_word> OP_TO_RA_SI
%token <y_word> OP_TOX_RA_RB
%token <y_word> OP_LA %token <y_word> OP_TOX_RA_SI
%token <y_word> OP_LI32 %token <y_word> OP_clrlsldi OP_clrldi OP_clrrdi OP_extldi OP_extrdi
%token <y_word> OP_insrdi OP_rotrdi OP_sldi OP_srdi
%token <y_word> OP_POWERPC_FIXUP %token <y_word> OP_clrlslwi OP_clrlwi OP_clrrwi OP_extlwi OP_extrwi
%token <y_word> OP_HI OP_HA OP_LO %token <y_word> OP_inslwi OP_insrwi OP_rotlwi OP_rotrwi OP_slwi OP_srwi
/* Other token types */ /* Other token types */
%type <y_word> c %type <y_word> c
%type <y_word> e16 u8 u7 u6 u5 u4 u2 u1 %type <y_word> e16 negate16 u8 u7 u6 u5 u4 u2 u1
%type <y_word> nb ds bda bdl lia lil spr_num %type <y_word> opt_bh cr_opt nb ds bda bdl lia lil spr_num

View file

@ -99,9 +99,6 @@
/* Special instructions */ /* Special instructions */
0, OP_LI32, 0, "li32", 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_HI, 0, "hi16",
0, OP_HA, 0, "ha16", 0, OP_HA, 0, "ha16",
0, OP_LO, 0, "lo16", 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 | 193<<1, "crxor",
0, OP_BT_BA_BB, 19<<26 | 225<<1, "crnand", 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 | 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 | 129<<1, "crandc",
0, OP_BT_BA_BB, 19<<26 | 417<<1, "crorc", 0, OP_BT_BA_BB, 19<<26 | 417<<1, "crorc",
0, OP_BF_BFA, 19<<26 | 0<<1, "mcrf", 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) */ /* Fixed point instructions (page 29) */
0, OP_RT_RA_D, 34<<26, "lbz", 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_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_addic, 12<<26, "addic", /* special case C */
0, OP_RT_RA_SI, 8<<26, "subfic", 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 | 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 | 1<<10 | 138<<1, "addeo",
0, OP_RT_RA_RB_C, 31<<26 | 0<<10 | 136<<1, "subfe", 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 | 0<<10 | 104<<1, "neg",
0, OP_RT_RA_C, 31<<26 | 1<<10 | 104<<1, "nego", 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 */ /* page 54 */
0, OP_RT_RA_SI, 7<<26, "mulli", 0, OP_RT_RA_SI, 7<<26, "mulli",
0, OP_RT_RA_RB_C, 31<<26 | 0<<10 | 233<<1, "mulld", 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_UI, 10<<26, "cmpli",
0, OP_BF_L_RA_RB, 31<<26 | 32<<1, "cmpl", 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 */ /* page 60 */
0, OP_TO_RA_SI, 2<<26, "tdi", 0, OP_TO_RA_SI, 2<<26, "tdi",
0, OP_TO_RA_SI, 3<<26, "twi", 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 | 68<<1, "td",
0, OP_TO_RA_RB, 31<<26 | 4<<1, "tw", 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 */ /* page 62 */
0, OP_RS_RA_UI_CC, 28<<26, "andi", /* C compulsory */ 0, OP_RS_RA_UI_CC, 28<<26, "andi", /* C compulsory */
0, OP_RS_RA_UI_CC, 29<<26, "andis", /* 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 | 58<<1, "cntlzd",
0, OP_RS_RA_C, 31<<26 | 26<<1, "cntlzw", 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 */ /* page 69 */
0, OP_RS_RA_SH_MB6_SH_C, 30<<26 | 0<<2, "rldicl", 0, OP_RA_RS_SH6_MB6_C, 30<<26 | 0<<2, "rldicl",
0, OP_RS_RA_SH_ME6_SH_C, 30<<26 | 1<<2, "rldicr", 0, OP_RA_RS_SH6_MB6_C, 30<<26 | 1<<2, "rldicr",
0, OP_RS_RA_SH_MB6_SH_C, 30<<26 | 2<<2, "rldic", 0, OP_RA_RS_SH6_MB6_C, 30<<26 | 2<<2, "rldic",
0, OP_RS_RA_SH_MB5_ME5_C, 21<<26, "rlwinm", 0, OP_RA_RS_SH5_MB5_ME5_C, 21<<26, "rlwinm",
0, OP_RS_RA_RB_MB6_C, 30<<26 | 8<<1, "rldcl", 0, OP_RA_RS_RB_MB6_C, 30<<26 | 8<<1, "rldcl",
0, OP_RS_RA_RB_ME6_C, 30<<26 | 9<<1, "rldcr", 0, OP_RA_RS_RB_MB6_C, 30<<26 | 9<<1, "rldcr",
0, OP_RS_RA_RB_MB5_ME5_C, 23<<26, "rlwnm", 0, OP_RA_RS_RB_MB5_ME5_C, 23<<26, "rlwnm",
0, OP_RS_RA_SH_MB6_SH_C, 30<<26 | 3<<2, "rldimi", 0, OP_RA_RS_SH6_MB6_C, 30<<26 | 3<<2, "rldimi",
0, OP_RS_RA_SH_MB5_ME5_C, 20<<26, "rlwimi", 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 */ /* page 74 */
0, OP_RS_RA_RB_C, 31<<26 | 27<<1, "sld", 0, OP_RA_RS_RB_C, 31<<26 | 27<<1, "sld",
0, OP_RS_RA_RB_C, 31<<26 | 24<<1, "slw", 0, OP_RA_RS_RB_C, 31<<26 | 24<<1, "slw",
0, OP_RS_RA_RB_C, 31<<26 | 539<<1, "srd", 0, OP_RA_RS_RB_C, 31<<26 | 539<<1, "srd",
0, OP_RS_RA_RB_C, 31<<26 | 536<<1, "srw", 0, OP_RA_RS_RB_C, 31<<26 | 536<<1, "srw",
0, OP_RS_RA_SH6_C, 31<<26 | 413<<2, "sradi", 0, OP_RA_RS_SH6_C, 31<<26 | 413<<2, "sradi",
0, OP_RS_RA_SH5_C, 31<<26 | 824<<1, "srawi", 0, OP_RA_RS_SH5_C, 31<<26 | 824<<1, "srawi",
0, OP_RS_RA_RB_C, 31<<26 | 794<<1, "srad", 0, OP_RA_RS_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 | 792<<1, "sraw",
/* page 78 */ /* page 78 */
0, OP_RS_SPR, 31<<26 | 467<<1, "mtspr", 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_RS_FXM, 31<<26 | 0<<21 | 144<<1, "mtcrf",
0, OP_RT, 31<<26 | 0<<21 | 19<<1, "mfcr", 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) */ /* Floating point instructions (page 83) */
0, OP_FRT_RA_D, 48<<26, "lfs", 0, OP_FRT_RA_D, 48<<26, "lfs",

View file

@ -4,16 +4,33 @@
*/ */
operation 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_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_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_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_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_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_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_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_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_BT_C c u5 { emit4($1 | $2 | ($3<<21)); }
| OP_FLM_FRB_C c u8 ',' FPR { emit4($1 | $2 | ($3<<17) | ($5<<11)); } | 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); } | 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_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_RA_RB FPR ',' GPR ',' GPR { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); }
| OP_FRT_C c FPR { emit4($1 | $2 | ($3<<21)); } | 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 GPR { emit4($1 | ($2<<21)); }
| OP_RT_RA_C c GPR ',' GPR { emit4($1 | $2 | ($3<<21) | ($5<<16)); } | 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_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_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_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 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 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_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_RT_SPR GPR ',' spr_num { emit4($1 | ($2<<21) | ($4<<11)); }
| OP_RS_FXM u7 ',' GPR { emit4($1 | ($4<<21) | ($2<<12)); } | 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_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 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_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_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_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_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_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_LEV u7 { emit4($1 | ($2<<5)); }
| OP_LIA lia { emit4($1 | $2); } | OP_LIA lia { emit4($1 | $2); }
| OP_LIL lil { emit4($1 | $2); } | OP_LIL lil { emit4($1 | $2); }
| OP_LI32 li32 /* emitted in subrule */ | 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 c
@ -80,6 +223,17 @@ e16
| OP_LO ASC_LPAR expr ASC_RPAR { $$ = emit_lo(&$3); } | 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 u8
: absexp : 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 ds
: e16 : e16
{ {
@ -251,14 +418,3 @@ spr_num
$$ = ($1 >> 5) | (($1 & 0x1f) << 5); $$ = ($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);
}
;

View file

@ -1,12 +1,5 @@
#
! $Source$
! $State$
! $Revision$
#include "powerpc.h"
.sect .text .sect .text
! Index into a bounds-checked array. ! Index into a bounds-checked array.
! !
! On entry: ! On entry:
@ -20,19 +13,20 @@
.define .aar4 .define .aar4
.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 mtspr ctr, r0 ! load CTR with trap address
lwz r0, 0(r3) lwz r0, 0(r3)
subf. r4, r0, r4 ! adjust range subf. r4, r0, r4 ! adjust range
bcctr IFTRUE, LT, 0 ! check lower bound bltctr ! check lower bound
lwz r0, 4(r3) lwz r0, 4(r3)
cmpl cr0, 0, r4, r3 cmplw r4, r3
bcctr IFFALSE, LT, 0 ! check upper bound bgectr ! check upper bound
lwz r0, 8(r3) lwz r0, 8(r3)
mullw r4, r4, r0 ! scale index mullw r4, r4, r0 ! scale index
add r3, r4, r5 ! calculate element address add r3, r4, r5 ! calculate element address
bclr ALWAYS, 0, 0 blr

View file

@ -1,5 +1,3 @@
#include "powerpc.h"
.sect .text .sect .text
! Set intersection. ! Set intersection.
@ -12,7 +10,7 @@
mr r4, sp ! r4 = ptr to set a mr r4, sp ! r4 = ptr to set a
add r5, sp, r3 ! r5 = ptr to set b 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 mtspr ctr, r6 ! ctr = r3 / 4
1: 1:
lwz r7, 0(r4) lwz r7, 0(r4)
@ -21,6 +19,6 @@
stw r8, 0(r5) stw r8, 0(r5)
addi r4, r4, 4 addi r4, r4, 4
addi r5, r5, 4 addi r5, r5, 4
bc DNZ, 0, 1b ! loop ctr times bdnz 1b ! loop ctr times
add sp, sp, r3 add sp, sp, r3
bclr ALWAYS, 0, 0 blr

View file

@ -1,14 +1,12 @@
for _, plat in ipairs(vars.plats) do for _, plat in ipairs(vars.plats) do
acklibrary { acklibrary {
name = "headers_"..plat, name = "headers_"..plat,
hdrs = { "./*.h" }
} }
acklibrary { acklibrary {
name = "lib_"..plat, name = "lib_"..plat,
srcs = { srcs = {
"./*.s", -- zer.s "./*.s",
"./*.e",
}, },
vars = { plat = plat }, vars = { plat = plat },
deps = { deps = {

View file

@ -1,10 +1,3 @@
#
! $Source$
! $State$
! $Revision$
#include "powerpc.h"
.sect .text .sect .text
! Converts a 64-bit double into a 32-bit integer. ! Converts a 64-bit double into a 32-bit integer.
@ -17,4 +10,4 @@
fctiwz f0, f0 fctiwz f0, f0
stfd f0, 0(sp) stfd f0, 0(sp)
addi sp, sp, 4 addi sp, sp, 4
bclr ALWAYS, 0, 0 ! ...and return blr

View file

@ -1,10 +1,3 @@
#
! $Source$
! $State$
! $Revision$
#include "powerpc.h"
.sect .text .sect .text
! Converts a 64-bit double into a 32-bit unsigned integer. ! Converts a 64-bit double into a 32-bit unsigned integer.
@ -13,17 +6,17 @@
.define .cfu8 .define .cfu8
.cfu8: .cfu8:
li32 r3, .fd_00000000 lis r3, ha16[.fd_00000000]
lfd f0, 0(r3) ! f0 = 0.0 lfd f0, lo16[.fd_00000000](r3) ! f0 = 0.0
lfd f1, 0(sp) ! value to be converted lfd f1, 0(sp) ! value to be converted
li32 r3, .fd_FFFFFFFF lis r3, ha16[.fd_FFFFFFFF]
lfd f3, 0(r3) ! f3 = 0xFFFFFFFF 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 fsel f2, f1, f1, f0
fsub f5, f3, f1 fsub f5, f3, f1
fsel f2, f5, f2, f3 fsel f2, f5, f2, f3
@ -34,11 +27,11 @@
stfd f2, 0(sp) stfd f2, 0(sp)
addi sp, sp, 4 addi sp, sp, 4
bclr IFTRUE, LT, 0 bltlr
lwz r3, 0(sp) lwz r3, 0(sp)
xoris r3, r3, 0x8000 xoris r3, r3, 0x8000
stw r3, 0(sp) stw r3, 0(sp)
bclr ALWAYS, 0, 0 blr

View file

@ -1,9 +1,4 @@
# .sect .text; .sect .rom; .sect .data; .sect .bss
! $Source$
! $State$
! $Revision$
#include "powerpc.h"
.sect .text .sect .text
@ -14,22 +9,22 @@
.define .cif8 .define .cif8
.cif8: .cif8:
addi sp, sp, -4 ! make space for the double addi sp, sp, -4 ! make space for the double
lwz r3, 4(sp) lwz r3, 4(sp)
xoris r3, r3, 0x8000 xoris r3, r3, 0x8000
stw r3, 4(sp) ! flip sign of integer value stw r3, 4(sp) ! flip sign of integer value
addis r3, r0, 0x4330 addis r3, r0, 0x4330
stw r3, 0(sp) ! set high word to construct a double stw r3, 0(sp) ! set high word to construct a double
lfd f0, 0(sp) ! load value lfd f0, 0(sp) ! load value
li32 r3, pivot lis r3, ha16[pivot]
lfd f1, 0(r3) ! load pivot value lfd f1, lo16[pivot](r3) ! load pivot value
fsub f0, f0, f1 ! adjust fsub f0, f0, f1 ! adjust
stfd f0, 0(sp) ! save value again... stfd f0, 0(sp) ! save value again...
bclr ALWAYS, 0, 0 ! ...and return blr ! ...and return
.sect .rom .sect .rom
pivot: pivot:

View file

@ -1,5 +1,3 @@
#include "powerpc.h"
.sect .text .sect .text
! Compare sets a, b. ! Compare sets a, b.
@ -12,21 +10,21 @@
mr r4, sp ! r4 = ptr to set a mr r4, sp ! r4 = ptr to set a
add r5, sp, r3 ! r5 = ptr to set b add r5, sp, r3 ! r5 = ptr to set b
mr r6, r3 ! r6 = size mr r6, r3 ! r6 = size
rlwinm r3, r3, 30, 2, 31 srwi r3, r3, 2
mtspr ctr, r3 ! ctr = size / 4 mtspr ctr, r3 ! ctr = size / 4
1: 1:
lwz r7, 0(r4) lwz r7, 0(r4)
lwz r8, 0(r5) 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 r4, r4, 4
addi r5, r5, 4 addi r5, r5, 4
bc IFFALSE, EQ, 2f ! branch if not equal bne cr0, 2f ! branch if not equal
bc DNZ, 0, 1b ! loop ctr times bdnz 1b ! loop ctr times
addi r3, r0, 0 ! equal: return 0 addi r3, r0, 0 ! equal: return 0
b 3f b 3f
2: 2:
addi r3, r0, 1 ! not equal: return 1 addi r3, r0, 1 ! not equal: return 1
3: 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 add sp, sp, r6 ! remove sets from stack
bclr ALWAYS, 0, 0 blr

View file

@ -1,5 +1,3 @@
#include "powerpc.h"
.sect .text .sect .text
! Set complement. ! Set complement.
@ -11,12 +9,12 @@
addi sp, sp, 4 addi sp, sp, 4
mr r4, sp ! r4 = pointer to set a mr r4, sp ! r4 = pointer to set a
rlwinm r5, r3, 30, 2, 31 srwi r5, r3, 2
mtspr ctr, r5 ! ctr = r3 / 4 mtspr ctr, r5 ! ctr = r3 / 4
1: 1:
lwz r6, 0(r4) lwz r6, 0(r4)
nor r6, r6, r6 ! complement of word nor r6, r6, r6 ! complement of word
stw r6, 0(r4) stw r6, 0(r4)
addi r4, r4, 4 addi r4, r4, 4
bc DNZ, 0, 1b ! loop ctr times bdnz 1b ! loop ctr times
bclr ALWAYS, 0, 0 blr

View file

@ -1,10 +1,3 @@
#
! $Source$
! $State$
! $Revision$
#include "powerpc.h"
.sect .text .sect .text
! this is not a subroutine, but just a ! this is not a subroutine, but just a
@ -25,23 +18,17 @@
lwz r5, 4(r3) ! fetch lower bound lwz r5, 4(r3) ! fetch lower bound
subf. r4, r5, r4 ! adjust value 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 lwz r5, 8(r3) ! fetch range
cmp cr0, 0, r4, r5 cmplw r4, r5
bcctr IFTRUE, GT, 0 ! jump to default if out of range bgtctr ! jump to default if out of range
addi r3, r3, 12 ! skip header addi r3, r3, 12 ! skip header
rlwinm r4, r4, 2, 0, 31-2 ! scale value (<<2) slwi r4, r4, 2 ! scale value (<<2)
b 1f
1:
lwzx r5, r3, r4 ! load target lwzx r5, r3, r4 ! load target
b 1f
1:
mtspr ctr, r5 mtspr ctr, r5
or. r5, r5, r5 ! test it or. r5, r5, r5 ! test it
b 1f bnectr ! jump to target if non-zero
1:
bcctr IFFALSE, EQ, 0 ! jump to target if non-zero
b .trap_ecase ! otherwise trap b .trap_ecase ! otherwise trap

View file

@ -1,10 +1,3 @@
#
! $Source$
! $State$
! $Revision$
#include "powerpc.h"
.sect .text .sect .text
! this is not a subroutine, but just a ! this is not a subroutine, but just a
@ -22,21 +15,21 @@
lwz r5, 0(r3) ! load default lwz r5, 0(r3) ! load default
mtspr ctr, r5 mtspr ctr, r5
lwz r6, 4(r3) ! fetch count lwz r6, 4(r3) ! fetch count
1: 1:
or. r6, r6, r6 ! test count or. r6, r6, r6 ! test count
bcctr IFTRUE, EQ, 0 ! exit if zero beqctr ! exit if zero
addi r6, r6, -1 ! otherwise decrement addi r6, r6, -1 ! otherwise decrement
lwzu r7, 8(r3) ! fetch target index, increment pointer lwzu r7, 8(r3) ! fetch target index, increment pointer
cmp cr0, 0, r4, r7 ! compare with value cmpw r4, r7 ! compare with value
bc IFFALSE, EQ, 1b ! if not equal, go again bne 1b ! if not equal, go again
lwz r7, 4(r3) ! fetch target address lwz r7, 4(r3) ! fetch target address
mtspr ctr, r7 mtspr ctr, r7
or. r7, r7, r7 ! test it 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 b .trap_ecase ! otherwise trap

View file

@ -1,10 +1,3 @@
#
! $Source$
! $State$
! $Revision$
#include "powerpc.h"
.sect .text .sect .text
! Converts a 32-bit unsigned integer into a 64-bit double. ! Converts a 32-bit unsigned integer into a 64-bit double.
@ -14,18 +7,18 @@
.define .cuf8 .define .cuf8
.cuf8: .cuf8:
addi sp, sp, -4 ! make space for the double 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 stw r3, 0(sp) ! set high word to construct a double
lfd f0, 0(sp) ! load value lfd f0, 0(sp) ! load value
li32 r3, pivot lis r3, ha16[pivot]
lfd f1, 0(r3) ! load pivot value lfd f1, lo16[pivot](r3) ! load pivot value
fsub f0, f0, f1 ! adjust fsub f0, f0, f1 ! adjust
stfd f0, 0(sp) ! save value again... stfd f0, 0(sp) ! save value again...
bclr ALWAYS, 0, 0 ! ...and return blr ! ...and return
.sect .rom .sect .rom
pivot: pivot:

View file

@ -1,10 +1,5 @@
# .sect .text; .sect .rom; .sect .data; .sect .bss
! $Source$
! $State$
! $Revision$
#include "powerpc.h"
.sect .rom .sect .rom
! Contains a handy double-precision zero. (Also works as a single-precision ! Contains a handy double-precision zero. (Also works as a single-precision

View file

@ -1,10 +1,5 @@
# .sect .text; .sect .rom; .sect .data; .sect .bss
! $Source$
! $State$
! $Revision$
#include "powerpc.h"
.sect .rom .sect .rom
! Contains a handy double-precision 0x80000000. ! Contains a handy double-precision 0x80000000.

View file

@ -1,15 +1,10 @@
# .sect .text; .sect .rom; .sect .data; .sect .bss
! $Source$
! $State$
! $Revision$
#include "powerpc.h"
.sect .rom .sect .rom
! Contains a handy double-precision 0xFFFFFFFF. ! Contains a handy double-precision 0xFFFFFFFF.
.define .fd_FFFFFFFF .define .fd_FFFFFFFF
.fd_FFFFFFFF: .fd_FFFFFFFF:
!float 4.294967295e+9 sz 8 !float 4.294967295e+9 sz 8
.data1 0101,0357,0377,0377,0377,0340,00,00 .data1 0101,0357,0377,0377,0377,0340,00,00

View file

@ -1,4 +1,4 @@
#include "powerpc.h" .sect .text; .sect .rom; .sect .data; .sect .bss
.sect .text .sect .text
@ -10,46 +10,44 @@
! r3 = fraction, high word (bits 0..31) ! r3 = fraction, high word (bits 0..31)
! r4 = fraction, low word (bits 32..63) ! r4 = fraction, low word (bits 32..63)
! r5 = exponent ! r5 = exponent
! Kills: cr0 f0 f1 r6 r7
.define .fef8 .define .fef8
.fef8: .fef8:
! IEEE double-precision format: ! IEEE double-precision format:
! sign exponent fraction ! sign exponent fraction
! 0 1..11 12..63 ! 0 1..11 12..63
rlwinm r6, r3, 12, 21, 31 ! r6 = IEEE exponent extrwi r6, r3, 11, 1 ! r6 = IEEE exponent
addis r7, r0, 0x7ff0 ! r7 = exponent mask
addi r5, r6, -1022 ! r5 = true exponent addi r5, r6, -1022 ! r5 = true exponent
cmpi cr0, 0, r6, 2047 cmpwi r6, 2047
bclr IFTRUE, EQ, 0 ! return if infinity or NaN beqlr ! return if infinity or NaN
cmpi cr0, 0, r6, 0 cmpwi r6, 0
bc IFFALSE, EQ, 1f ! jump if normalized number bne 1f ! jump if normalized number
! Got denormalized number or zero, probably zero. ! 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 addi r5, r0, 0 ! r5 = true exponent = 0
or. r6, r6, r4 ! r6 = high|low fraction or. r6, r6, r4 ! r6 = high|low fraction
bclr IFTRUE, EQ, 0 ! return if zero beqlr ! return if zero
! Got denormalized number, not zero. ! Got denormalized number, not zero.
stwu r4, -4(sp) stwu r4, -4(sp)
stwu r3, -4(sp) stwu r3, -4(sp)
li32 r6, _2_64
lfd f0, 0(sp) 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 fmul f0, f0, f1 ! multiply it by 2**64
stfd f0, 0(sp) stfd f0, 0(sp)
lwz r3, 0(sp) lwz r3, 0(sp)
lwz r4, 4(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 sp, sp, 8
addi r5, r6, -1022 - 64 ! r5 = true exponent addi r5, r6, -1022 - 64 ! r5 = true exponent
1: 1:
! Put fraction in [0.5, 1) or (-1, -0.5] by setting its ! Put fraction in [0.5, 1) or (-1, -0.5] by setting its
! exponent to true 0, IEEE 1022. ! 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 oris r3, r3, 1022 << 4 ! set new exponent
bclr ALWAYS, 0, 0 blr
.sect .rom .sect .rom
_2_64: _2_64:

View file

@ -1,5 +1,3 @@
#include "powerpc.h"
.sect .text .sect .text
! Multiplies two double-precision floats, then splits the product into ! Multiplies two double-precision floats, then splits the product into
@ -9,7 +7,6 @@
! Yields: ! Yields:
! f1 = fraction ! f1 = fraction
! f2 = integer ! f2 = integer
! Kills: cr0 f1 f2 r3 r4 r5 r6
.define .fif8 .define .fif8
.fif8: .fif8:
@ -25,17 +22,16 @@
! 0 to 51, then the IEEE fraction has that many integer bits. ! 0 to 51, then the IEEE fraction has that many integer bits.
! (IEEE has an implicit 1 before its fraction. If the IEEE ! (IEEE has an implicit 1 before its fraction. If the IEEE
! fraction has 0 integer bits, we still have an integer.) ! 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 addic. r5, r5, -1023 ! r5 = nr of integer bits
bc IFTRUE, LT, no_int blt no_int
cmpi cr0, 0, r5, 21 cmpwi r5, 21
bc IFTRUE, LT, small_int blt small_int
cmpi cr0, 0, r5, 52 cmpwi r5, 52
bc IFTRUE, LT, big_int blt big_int
! f1 is an integer without fraction. Jump to calculate ! f1 is an integer without fraction (or infinity or NaN).
! fraction f1 = f2 - f1. It will be zero (or perhaps NaN). fmr f2, f1 ! integer = f1
fmr f2, f1
b subtract b subtract
no_int: no_int:
@ -46,17 +42,17 @@ no_int:
small_int: small_int:
! f1 has r5 = 0 to 20 integer bits in the IEEE fraction. ! f1 has r5 = 0 to 20 integer bits in the IEEE fraction.
! High word has 20 - r5 fraction bits. ! High word has 20 - r5 fraction bits.
addi r6, r0, 20 li r6, 20
subf r6, r5, r6 subf r6, r5, r6
srw r3, r3, 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 slw r3, r3, r6 ! clear fraction in high word
b move_int b move_int
big_int: big_int:
! f1 has r5 = 21 to 51 to integer bits. ! f1 has r5 = 21 to 51 to integer bits.
! Low word has 52 - r5 fraction bits. ! Low word has 52 - r5 fraction bits.
addi r6, r0, 52 li r6, 52
subf r6, r5, r6 subf r6, r5, r6
srw r4, r4, r6 srw r4, r4, r6
slw r4, r4, r6 ! clear fraction in low word slw r4, r4, r6 ! clear fraction in low word
@ -68,4 +64,4 @@ subtract:
fsub f1, f1, f2 ! fraction = value - integer fsub f1, f1, f2 ! fraction = value - integer
done: done:
addi sp, sp, 8 ! restore stack pointer addi sp, sp, 8 ! restore stack pointer
bclr ALWAYS, 0, 0 blr

View file

@ -1,4 +1,4 @@
#include "powerpc.h" #
.sect .text .sect .text
@ -14,13 +14,13 @@
addi r5, sp, 8 /* r5 = base address of bit set */ addi r5, sp, 8 /* r5 = base address of bit set */
rlwinm r6, r4, 29, 3, 29 /* r6 = byte index of word in 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 */ lwzx r8, r5, r6 /* r8 = individual word from set */
sraw r8, r8, r7 srw r8, r8, r7
rlwinm r8, r8, 0, 31, 31 extrwi r8, r8, 1, 31
addi sp, sp, 8 /* retract over the two words */ addi sp, sp, 8 /* retract over the two words */
add sp, sp, r3 /* retract over bitfield */ add sp, sp, r3 /* retract over bitfield */
stwu r8, -4(sp) /* push result */ stwu r8, -4(sp) /* push result */
bclr ALWAYS, 0, 0 /* return */ blr /* return */

View file

@ -1,5 +1,3 @@
#include "powerpc.h"
.sect .text .sect .text
! Set union. ! Set union.
@ -12,7 +10,7 @@
mr r4, sp ! r4 = ptr to set a mr r4, sp ! r4 = ptr to set a
add r5, sp, r3 ! r5 = ptr to set b 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 mtspr ctr, r6 ! ctr = r3 / 4
1: 1:
lwz r7, 0(r4) lwz r7, 0(r4)
@ -21,6 +19,6 @@
stw r8, 0(r5) stw r8, 0(r5)
addi r4, r4, 4 addi r4, r4, 4
addi r5, r5, 4 addi r5, r5, 4
bc DNZ, 0, 1b ! loop ctr times bdnz 1b ! loop ctr times
add sp, sp, r3 add sp, sp, r3
bclr ALWAYS, 0, 0 blr

View file

@ -1,6 +1,3 @@
#
#include "powerpc.h"
.sect .text .sect .text
! Load from bounds-checked array. ! Load from bounds-checked array.
@ -18,19 +15,19 @@
! r3 = ptr to element ! r3 = ptr to element
! r0 = size of element ! r0 = size of element
cmpi cr0, 0, r0, 1 cmpwi r0, 1
bc IFFALSE, EQ, 1f bne 1f
! Load 1 byte. ! Load 1 byte.
lbz r4, 0(r3) lbz r4, 0(r3)
stwu r4, -4(sp) stwu r4, -4(sp)
bclr ALWAYS, 0, 0 blr
1: 1:
cmpi cr0, 0, r0, 2 cmpwi r0, 2
bc IFFALSE, EQ, 2f bne 2f
! Load 2 bytes. ! Load 2 bytes.
lhz r4, 0(r3) lhz r4, 0(r3)
stwu r4, -4(sp) stwu r4, -4(sp)
bclr ALWAYS, 0, 0 blr
2: 2:
! Load r0 bytes, where r0 must be a positive multiple of 4. ! Load r0 bytes, where r0 must be a positive multiple of 4.
subf sp, r0, sp ! move stack pointer down subf sp, r0, sp ! move stack pointer down
@ -39,5 +36,5 @@
addic. r5, r5, -4 ! r5 -= 4 addic. r5, r5, -4 ! r5 -= 4
lwzx r4, r5, r3 lwzx r4, r5, r3
stwx r4, r5, sp stwx r4, r5, sp
bc IFTRUE, GT, 3b ! loop if r5 > 0 bgt 3b ! loop if r5 > 0
bclr ALWAYS, 0, 0 blr

View file

@ -1,10 +1,3 @@
#
! $Source$
! $State$
! $Revision$
#include "powerpc.h"
.sect .text .sect .text
! Loads a variable-sized structure onto the stack. ! Loads a variable-sized structure onto the stack.
@ -15,32 +8,32 @@
.define .los .define .los
.los: .los:
! These sizes are handled specially. ! These sizes are handled specially.
cmpi cr0, 0, r3, 1 cmplwi r3, 1
bc IFFALSE, GT, size1 ble size1
cmpi cr0, 0, r3, 2 cmplwi r3, 2
bc IFFALSE, GT, size2 ble size2
cmpi cr0, 0, r3, 4 cmplwi r3, 4
bc IFFALSE, GT, size4 ble size4
! Variable-sized structure. ! Variable-sized structure.
addi r3, r3, 3 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 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 mtspr ctr, r3
1: 1:
lwzu r5, -4(r4) lwzu r5, -4(r4)
stwu r5, -4(sp) stwu r5, -4(sp)
bc DNZ, 0, 1b ! decrement CTR, jump if non-zero bdnz 1b ! decrement CTR, jump if non-zero
bclr ALWAYS, 0, 0 blr
size1: size1:
lbz r3, 0(r4) lbz r3, 0(r4)
b 1f b 1f
@ -51,4 +44,4 @@ size4:
lwz r3, 0(r4) lwz r3, 0(r4)
1: 1:
stwu r3, -4(sp) stwu r3, -4(sp)
bclr ALWAYS, 0, 0 blr

View file

@ -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

View file

@ -1,5 +1,3 @@
#include "powerpc.h"
.sect .text .sect .text
! Bounds check. Traps if the value is out of range. ! Bounds check. Traps if the value is out of range.
@ -12,11 +10,11 @@
addi sp, sp, 4 ! leave value on stack addi sp, sp, 4 ! leave value on stack
lwz r5, 0 (r3) lwz r5, 0 (r3)
cmp cr0, 0, r4, r5 cmpw r4, r5
bc IFTRUE, LT, .trap_erange blt .trap_erange
lwz r5, 4 (r3) lwz r5, 4 (r3)
cmp cr0, 0, r4, r5 cmpw r4, r5
bc IFTRUE, GT, .trap_erange bgt .trap_erange
bclr ALWAYS, 0, 0 blr

View file

@ -1,19 +1,12 @@
#
! $Source$
! $State$
! $Revision$
#include "powerpc.h"
.sect .text .sect .text
! Standard boilerplate for returning from functions. ! Standard boilerplate for returning from functions.
.define .ret .define .ret
.ret: .ret:
lwz r0, 4(fp) lwz r0, 4(fp)
mtspr lr, r0 mtspr lr, r0
lwz r0, 0(fp) ! our stack frame becomes invalid as soon as... lwz r0, 0(fp) ! our stack frame becomes invalid as soon as...
addi sp, fp, 8 ! ...we change sp addi sp, fp, 8 ! ...we change sp
or fp, r0, r0 mr fp, r0
bclr ALWAYS, 0, 0 blr

View file

@ -1,6 +1,3 @@
#
#include "powerpc.h"
.sect .text .sect .text
! Store to bounds-checked array. ! Store to bounds-checked array.
@ -18,21 +15,21 @@
! r3 = ptr to element ! r3 = ptr to element
! r0 = size of element ! r0 = size of element
cmpi cr0, 0, r0, 1 cmpwi r0, 1
bc IFFALSE, EQ, 1f bne 1f
! Store 1 byte. ! Store 1 byte.
lwz r4, 0(sp) lwz r4, 0(sp)
addi sp, sp, 4 addi sp, sp, 4
stb r4, 0(r3) stb r4, 0(r3)
bclr ALWAYS, 0, 0 blr
1: 1:
cmpi cr0, 0, r0, 2 cmpwi r0, 2
bc IFFALSE, EQ, 2f bne 2f
! Store 2 bytes. ! Store 2 bytes.
lwz r4, 0(sp) lwz r4, 0(sp)
addi sp, sp, 4 addi sp, sp, 4
sth r4, 0(r3) sth r4, 0(r3)
bclr ALWAYS, 0, 0 blr
2: 2:
! Store r0 bytes, where r0 must be a positive multiple of 4. ! Store r0 bytes, where r0 must be a positive multiple of 4.
or r5, r0, r0 ! index r5 = length r0 or r5, r0, r0 ! index r5 = length r0
@ -40,6 +37,6 @@
addic. r5, r5, -4 ! r5 -= 4 addic. r5, r5, -4 ! r5 -= 4
lwzx r4, r5, sp lwzx r4, r5, sp
stwx r4, r5, r3 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 add sp, r0, sp ! move stack pointer up
bclr ALWAYS, 0, 0 blr

View file

@ -1,5 +1,3 @@
#include "powerpc.h"
.sect .text .sect .text
! Create singleton set. ! Create singleton set.
@ -11,22 +9,22 @@
lwz r4, 4 (sp) lwz r4, 4 (sp)
addi sp, sp, 8 addi sp, sp, 8
rlwinm r7, r3, 30, 2, 31 srwi r7, r3, 2
neg r5, r3 neg r5, r3
add sp, sp, r5 ! allocate set add sp, sp, r5 ! allocate set
mr r6, sp ! r6 = ptr to set mr r6, sp ! r6 = ptr to set
mtspr ctr, r7 ! ctr = r3 / 4 mtspr ctr, r7 ! ctr = r3 / 4
1: 1:
rlwinm. r7, r4, 0, 0, 26 ! r7 = r4 & ~31 clrrwi. r7, r4, 5 ! r7 = r4 & ~31
bc IFTRUE, EQ, 2f ! branch if r4 in 0..31 beq 2f ! branch if r4 in 0..31
addi r5, r0, 0 ! no bit, word is zero li r5, 0 ! no bit, word is zero
b 3f b 3f
2: 2:
addi r5, r0, 1 li r5, 1
slw r5, r5, r4 ! yes bit, set bit in word slw r5, r5, r4 ! yes bit, set bit in word
3: 3:
stw r5, 0(r6) ! store word in set stw r5, 0(r6) ! store word in set
addi r4, r4, -32 addi r4, r4, -32
addi r6, r6, 4 addi r6, r6, 4
bc DNZ, 0, 1b ! loop ctr times bdnz 1b ! loop ctr times
bclr ALWAYS, 0, 0 blr

View file

@ -1,10 +1,3 @@
#
! $Source$
! $State$
! $Revision$
#include "powerpc.h"
.sect .text .sect .text
! Stores a variable-sized structure from the stack. ! Stores a variable-sized structure from the stack.
@ -15,35 +8,35 @@
.define .sts .define .sts
.sts: .sts:
! These sizes are handled specially. ! These sizes are handled specially.
lwz r5, 0(sp) lwz r5, 0(sp)
cmpi cr0, 0, r3, 1 cmplwi r3, 1
bc IFFALSE, GT, size1 ble size1
cmpi cr0, 0, r3, 2 cmplwi r3, 2
bc IFFALSE, GT, size2 ble size2
cmpi cr0, 0, r3, 4 cmplwi r3, 4
bc IFFALSE, GT, size4 ble size4
! Variable-sized structure. ! Variable-sized structure.
addi r3, r3, 3 addi r3, r3, 3
andi. r3, r3, ~3 ! align size clrrwi r3, r3, 2 ! align size
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 mtspr ctr, r3
1: 1:
lwz r5, 0(sp) lwz r5, 0(sp)
addi sp, sp, 4 addi sp, sp, 4
stw r5, 0(r4) stw r5, 0(r4)
addi r4, r4, 4 addi r4, r4, 4
bc DNZ, 0, 1b ! decrement CTR, jump if non-zero bdnz 1b ! decrement CTR, jump if non-zero
bclr ALWAYS, 0, 0 blr
size1: size1:
stb r5, 0(r4) stb r5, 0(r4)
b 1f b 1f
@ -54,4 +47,4 @@ size4:
stw r5, 0(r4) stw r5, 0(r4)
1: 1:
addi sp, sp, 4 addi sp, sp, 4
bclr ALWAYS, 0, 0 blr

View file

@ -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 .

View file

@ -1,5 +1,3 @@
#include "powerpc.h"
.sect .text .sect .text
! Set symmetric difference. ! Set symmetric difference.
@ -10,7 +8,7 @@
.xor: .xor:
mr r4, sp ! r4 = ptr to set a mr r4, sp ! r4 = ptr to set a
add r5, sp, r3 ! r5 = ptr to set b 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 mtspr ctr, r6 ! ctr = r3 / 4
1: 1:
lwz r7, 0(r4) lwz r7, 0(r4)
@ -19,6 +17,6 @@
stw r8, 0(r5) stw r8, 0(r5)
addi r4, r4, 4 addi r4, r4, 4
addi r5, r5, 4 addi r5, r5, 4
bc DNZ, 0, 1b ! loop ctr times bdnz 1b ! loop ctr times
add sp, sp, r3 add sp, sp, r3
bclr ALWAYS, 0, 0 blr

View file

@ -1,5 +1,3 @@
#include "powerpc.h"
.sect .text .sect .text
! Create empty set. ! Create empty set.
@ -10,8 +8,8 @@
lwz r3, 0(sp) lwz r3, 0(sp)
addi sp, sp, 4 addi sp, sp, 4
rlwinm r7, r3, 30, 2, 31 srwi r7, r3, 2
addi r4, r0, 0 ! r4 = zero li r4, 0 ! r4 = zero
neg r5, r3 neg r5, r3
add sp, sp, r5 ! allocate set add sp, sp, r5 ! allocate set
mr r6, sp ! r6 = ptr to set mr r6, sp ! r6 = ptr to set
@ -19,5 +17,5 @@
1: 1:
stw r4, 0(r6) ! store zero in set stw r4, 0(r6) ! store zero in set
addi r6, r6, 4 addi r6, r6, 4
bc DNZ, 0, 1b ! loop ctr times bdnz 1b ! loop ctr times
bclr ALWAYS, 0, 0 blr

View file

@ -10,7 +10,7 @@ INT64 = 8
FP_OFFSET = 0 /* Offset of saved FP relative to our FP */ FP_OFFSET = 0 /* Offset of saved FP relative to our FP */
PC_OFFSET = 4 /* Offset of saved PC 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) #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 los(n) (lo(n) | (((0-(lo(n)>>15)) & ~0xFFFF)))
#define his(n) ((hi(n) + (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 PROPERTIES
GPR /* any GPR */ GPR /* any GPR */
REG /* any allocatable GPR */ REG /* any allocatable GPR */
REG_PAIR /* speed hack for sti 8 */ REG_PAIR(8) /* speed hack for sti 8 */
FPR /* any FPR */ FPR(8) /* any FPR */
FREG /* any allocatable FPR */ FREG(8) /* any allocatable FPR */
FSREG /* any allocatable single-precision FPR */ FSREG /* any allocatable single-precision FPR */
SPR /* any SPR */ SPR /* any SPR */
CR /* any CR */ CR /* any CR */
@ -54,12 +45,10 @@ PROPERTIES
GPR16 GPR17 GPR18 GPR19 GPR20 GPR21 GPR22 GPR23 GPR16 GPR17 GPR18 GPR19 GPR20 GPR21 GPR22 GPR23
GPR24 GPR25 GPR26 GPR27 GPR28 GPR29 GPR30 GPR31 GPR24 GPR25 GPR26 GPR27 GPR28 GPR29 GPR30 GPR31
CR0 CR1 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)
FPR0 FPR1 FPR2 FPR3 FPR4 FPR5 FPR6 FPR7 FPR16(8) FPR17(8) FPR18(8) FPR19(8) FPR20(8) FPR21(8) FPR22(8) FPR23(8)
FPR8 FPR9 FPR10 FPR11 FPR12 FPR13 FPR14 FPR15 FPR24(8) FPR25(8) FPR26(8) FPR27(8) FPR28(8) FPR29(8) FPR30(8) FPR31(8)
FPR16 FPR17 FPR18 FPR19 FPR20 FPR21 FPR22 FPR23
FPR24 FPR25 FPR26 FPR27 FPR28 FPR29 FPR30 FPR31
REGISTERS REGISTERS
@ -85,7 +74,7 @@ REGISTERS
R14("r14") : GPR, REG, GPR14 regvar. R14("r14") : GPR, REG, GPR14 regvar.
R13("r13") : GPR, REG, GPR13 regvar. R13("r13") : GPR, REG, GPR13 regvar.
R12("r12") : GPR, REG, GPR12. R12("r12") : GPR, REG, GPR12.
R11("r11") : GPR, GPR11. R11("r11") : GPR, REG, GPR11.
R10("r10") : GPR, REG, GPR10. R10("r10") : GPR, REG, GPR10.
R9("r9") : GPR, REG, GPR9. R9("r9") : GPR, REG, GPR9.
R8("r8") : GPR, REG, GPR8. R8("r8") : GPR, REG, GPR8.
@ -158,9 +147,9 @@ REGISTERS
LR("lr") : SPR. LR("lr") : SPR.
CTR("ctr") : SPR. CTR("ctr") : SPR.
C0("cr0") : CR, CR0. CR0("cr0") : CR.
#define RSCRATCH R11 #define RSCRATCH R0
#define FSCRATCH F0 #define FSCRATCH F0
@ -200,13 +189,6 @@ TOKENS
SUM_RC = { GPR reg; INT off; } 4. SUM_RC = { GPR reg; INT off; } 4.
SUM_RR = { GPR reg1; GPR reg2; } 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_B = { GPR reg; } 4.
SEX_H = { GPR reg; } 4. SEX_H = { GPR reg; } 4.
@ -231,6 +213,20 @@ TOKENS
XOR_RIS = { GPR reg; INT valhi; } 4. XOR_RIS = { GPR reg; INT valhi; } 4.
XOR_RC = { GPR reg; INT val; } 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 SETS
@ -246,9 +242,6 @@ SETS
SUM_ALL = SUM_RC + SUM_RR. 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. SEX_ALL = SEX_B + SEX_H.
LOGICAL_ALL = NOT_R + AND_RR + OR_RR + OR_RC + XOR_RR + LOGICAL_ALL = NOT_R + AND_RR + OR_RR + OR_RC + XOR_RR +
@ -265,8 +258,7 @@ SETS
/* anything killed by sti (store indirect) */ /* anything killed by sti (store indirect) */
MEMORY = IND_ALL_BHW + IND_ALL_D. MEMORY = IND_ALL_BHW + IND_ALL_D.
OP_ALL_W = SUM_ALL + TRISTATE_ALL + SEX_ALL + LOGICAL_ALL + OP_ALL_W = SUM_ALL + SEX_ALL + LOGICAL_ALL + IND_ALL_W.
IND_ALL_W.
INSTRUCTIONS INSTRUCTIONS
@ -293,14 +285,27 @@ INSTRUCTIONS
andisX "andis." GPR:wo:cc, GPR:ro, CONST:ro. andisX "andis." GPR:wo:cc, GPR:ro, CONST:ro.
b LABEL:ro. b LABEL:ro.
bc CONST:ro, CONST:ro, 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. bcctr CONST:ro, CONST:ro, CONST:ro.
bctr.
bcctrl CONST:ro, CONST:ro, CONST:ro. bcctrl CONST:ro, CONST:ro, CONST:ro.
bctrl.
bclr CONST:ro, CONST:ro, CONST:ro. bclr CONST:ro, CONST:ro, CONST:ro.
bl LABEL:ro. bl LABEL:ro.
cmp CR:ro, CONST:ro, GPR:ro, GPR:ro kills :cc. 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. 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. 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. 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). divw GPR:wo, GPR:ro, GPR:ro cost(4, 23).
divwu 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. eqv GPR:wo, GPR:ro, GPR:ro.
@ -308,7 +313,8 @@ INSTRUCTIONS
extsh GPR:wo, GPR:ro. extsh GPR:wo, GPR:ro.
fadd FREG:wo, FREG:ro, FREG:ro cost(4, 5). fadd FREG:wo, FREG:ro, FREG:ro cost(4, 5).
fadds FSREG:wo, FSREG:ro, FSREG: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). fdiv FREG:wo, FREG:ro, FREG:ro cost(4, 35).
fdivs FSREG:wo, FSREG:ro, FSREG:ro cost(4, 21). fdivs FSREG:wo, FSREG:ro, FSREG:ro cost(4, 21).
fmr FPR:wo, FPR:ro cost(4, 5). fmr FPR:wo, FPR:ro cost(4, 5).
@ -349,6 +355,8 @@ INSTRUCTIONS
oris GPR:wo, GPR:ro, CONST:ro. oris GPR:wo, GPR:ro, CONST:ro.
orX "or." GPR:wo:cc, GPR:ro, GPR:ro. orX "or." GPR:wo:cc, GPR:ro, GPR:ro.
rlwinm GPR:wo, GPR:ro, CONST:ro, CONST:ro, CONST: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. slw GPR:wo, GPR:ro, GPR:ro.
subf GPR:wo, GPR:ro, GPR:ro. subf GPR:wo, GPR:ro, GPR:ro.
sraw GPR:wo, GPR:ro, GPR:ro cost(4, 2). sraw GPR:wo, GPR:ro, GPR:ro cost(4, 2).
@ -566,67 +574,6 @@ MOVES
COMMENT("move FPR->IND_RR_W") COMMENT("move FPR->IND_RR_W")
stfdx %1, %2.reg1, %2.reg2 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 */ /* Logicals */
from NOT_R to GPR from NOT_R to GPR
@ -669,6 +616,71 @@ MOVES
COMMENT("move XOR_RC->GPR") COMMENT("move XOR_RC->GPR")
xori %2, %1.reg, {CONST, %1.val} 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 */ /* Miscellaneous */
from OP_ALL_W + LABEL + CONST_ALL to GPRE from OP_ALL_W + LABEL + CONST_ALL to GPRE
@ -720,9 +732,9 @@ STACKINGRULES
extsh RSCRATCH, %1.reg extsh RSCRATCH, %1.reg
stwu RSCRATCH, {GPRINDIRECT, SP, 0-4} stwu RSCRATCH, {GPRINDIRECT, SP, 0-4}
from SUM_ALL + TRISTATE_ALL + LOGICAL_ALL to STACK from SUM_ALL + LOGICAL_ALL to STACK
gen gen
COMMENT("stack SUM_ALL + TRISTATE_ALL + LOGICAL_ALL") COMMENT("stack SUM_ALL + LOGICAL_ALL")
move %1, RSCRATCH move %1, RSCRATCH
stwu RSCRATCH, {GPRINDIRECT, SP, 0-4} stwu RSCRATCH, {GPRINDIRECT, SP, 0-4}
@ -804,7 +816,7 @@ COERCIONS
extsh %a, %1.reg extsh %a, %1.reg
yields %a yields %a
from SUM_ALL + TRISTATE_ALL + LOGICAL_ALL from SUM_ALL + LOGICAL_ALL
uses REG uses REG
gen gen
move %1, %a move %1, %a
@ -1683,153 +1695,337 @@ PATTERNS
cal ".inn" cal ".inn"
/* Boolean resolutions */ /* Boolean resolutions */
pat teq /* top = (top == 0) */ pat teq /* top = (top == 0) */
with TRISTATE_ALL + GPR with REG
uses reusing %1, REG uses reusing %1, REG
gen gen
move %1, C0 test %1
move C0, RSCRATCH mfcr %a
move {LABEL, ".teq_table"}, %a move {XEQ, %a}, %a
lwzx %a, %a, RSCRATCH
yields %a yields %a
pat tne /* top = (top != 0) */ pat tne /* top = (top != 0) */
with TRISTATE_ALL + GPR with REG
uses reusing %1, REG uses reusing %1, REG
gen gen
move %1, C0 test %1
move C0, RSCRATCH mfcr %a
move {LABEL, ".tne_table"}, %a move {XNE, %a}, %a
lwzx %a, %a, RSCRATCH
yields %a yields %a
pat tlt /* top = (top < 0) */ pat tlt /* top = (top < 0) */
with TRISTATE_ALL + GPR with REG
uses reusing %1, REG uses reusing %1, REG
gen gen
move %1, C0 test %1
move C0, RSCRATCH mfcr %a
move {LABEL, ".tlt_table"}, %a move {XLT, %a}, %a
lwzx %a, %a, RSCRATCH
yields %a yields %a
pat tle /* top = (top <= 0) */ pat tle /* top = (top <= 0) */
with TRISTATE_ALL + GPR with REG
uses reusing %1, REG uses reusing %1, REG
gen gen
move %1, C0 test %1
move C0, RSCRATCH mfcr %a
move {LABEL, ".tle_table"}, %a move {XLE, %a}, %a
lwzx %a, %a, RSCRATCH
yields %a yields %a
pat tgt /* top = (top > 0) */ pat tgt /* top = (top > 0) */
with TRISTATE_ALL + GPR with REG
uses reusing %1, REG uses reusing %1, REG
gen gen
move %1, C0 test %1
move C0, RSCRATCH mfcr %a
move {LABEL, ".tgt_table"}, %a move {XGT, %a}, %a
lwzx %a, %a, RSCRATCH
yields %a yields %a
pat tge /* top = (top >= 0) */ pat tge /* top = (top >= 0) */
with TRISTATE_ALL + GPR with REG
uses reusing %1, REG uses reusing %1, REG
gen gen
move %1, C0 test %1
move C0, RSCRATCH mfcr %a
move {LABEL, ".tge_table"}, %a move {XGE, %a}, %a
lwzx %a, %a, RSCRATCH
yields %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
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 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 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 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 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 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 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 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 */ /* Simple branches */
pat zeq /* Branch if signed top == 0 */ proc zxx example zeq
with TRISTATE_ALL+GPR STACK with REG STACK
gen gen
move %1, C0 test %1
bc IFTRUE, EQ, {LABEL, $1} bxx* {LABEL, $1}
pat beq /* Pop signed int, branch if... */
leaving pat zeq call zxx("beq") /* top == 0 */
cmi INT32 pat zne call zxx("bne") /* top != 0 */
zeq $1 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 */
pat zne /* Branch if signed top != 0 */ /* The peephole optimizer rewrites
with TRISTATE_ALL+GPR STACK * cmi 4 zeq
* as beq, and does same for bne, bgt, and so on.
*/
proc bxx example beq
with REG CONST2 STACK
gen gen
move %1, C0 cmpwi %1, {CONST, %2.val}
bc IFFALSE, EQ, {LABEL, $1} bxx[2] {LABEL, $1}
with CONST2 REG STACK
pat bne
leaving
cmi INT32
zne $1
pat zgt /* Branch if signed top > 0 */
with TRISTATE_ALL+GPR STACK
gen gen
move %1, C0 cmpwi %2, {CONST, %1.val}
bc IFTRUE, GT, {LABEL, $1} bxx[1] {LABEL, $1}
with REG REG STACK
pat bgt
leaving
cmi INT32
zgt $1
pat zge /* Branch if signed top >= 0 */
with TRISTATE_ALL+GPR STACK
gen gen
move %1, C0 cmpw %2, %1
bc IFFALSE, LT, {LABEL, $1} bxx[1] {LABEL, $1}
pat bge /* Pop two signed ints, branch if... */
leaving pat beq call bxx("beq", "beq") /* second == top */
cmi INT32 pat bne call bxx("bne", "bne") /* second != top */
zge $1 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 zlt /* Branch if signed top < 0 */ proc cmu4zxx example cmu zeq
with TRISTATE_ALL+GPR STACK with REG CONST2 STACK
gen gen
move %1, C0 cmplwi %1, {CONST, %2.val}
bc IFTRUE, LT, {LABEL, $1} bxx[2] {LABEL, $2}
with CONST2 REG STACK
pat blt
leaving
cmi INT32
zlt $1
pat zle /* Branch if signed top >= 0 */
with TRISTATE_ALL+GPR STACK
gen gen
move %1, C0 cmplwi %2, {CONST, %1.val}
bc IFFALSE, GT, {LABEL, $1} bxx[1] {LABEL, $2}
with REG REG STACK
gen
cmplw %2, %1
bxx[1] {LABEL, $2}
pat ble /* Pop two unsigned ints, branch if... */
leaving pat cmu zeq $1==4 call cmu4zxx("beq", "beq")
cmi INT32 pat cmu zne $1==4 call cmu4zxx("bne", "bne")
zle $1 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 */ pat cmi $1==INT32 /* Signed tristate compare */
with CONST_ALL GPR with REG CONST2
yields {TRISTATE_RC_S, %2, %1.val} uses reusing %1, REG={COND_RC, %1, %2.val}
with GPR GPR gen rlwinm %a, %a, {CONST, 1}, {CONST, 31}, {CONST, 0}
yields {TRISTATE_RR_S, %2, %1} 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 */ pat cmu $1==INT32 /* Unsigned tristate compare */
with CONST_ALL GPR with REG UCONST2
yields {TRISTATE_RC_U, %2, %1.val} uses reusing %1, REG={CONDL_RC, %1, %2.val}
with GPR GPR gen rlwinm %a, %a, {CONST, 1}, {CONST, 31}, {CONST, 0}
yields {TRISTATE_RR_U, %2, %1} 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 */ pat cmp /* Compare pointers */
leaving leaving
@ -1852,12 +2048,14 @@ PATTERNS
/* Other branching and labelling */ /* Other branching and labelling */
pat lab topeltsize($1)==4 && !fallthrough($1) pat lab topeltsize($1)==4 && !fallthrough($1)
kills ALL
gen gen
labeldef $1 labeldef $1
yields R3 yields R3
pat lab topeltsize($1)==4 && fallthrough($1) pat lab topeltsize($1)==4 && fallthrough($1)
with GPR3 with GPR3 STACK
kills ALL
gen gen
labeldef $1 labeldef $1
yields %1 yields %1
@ -1893,7 +2091,7 @@ PATTERNS
kills ALL kills ALL
gen gen
mtspr CTR, %1 mtspr CTR, %1
bcctrl ALWAYS, {CONST, 0}, {CONST, 0} bctrl.
pat lfr $1==INT32 /* Load function result, word */ pat lfr $1==INT32 /* Load function result, word */
yields R3 yields R3
@ -2020,7 +2218,7 @@ PATTERNS
move {IND_RC_W, %a, 4}, SP move {IND_RC_W, %a, 4}, SP
move {IND_RC_W, %a, 0}, %a move {IND_RC_W, %a, 0}, %a
mtspr CTR, %a mtspr CTR, %a
bcctr ALWAYS, {CONST, 0}, {CONST, 0} bctr.
pat lor $1==0 /* Load FP */ pat lor $1==0 /* Load FP */
uses REG uses REG
@ -2073,12 +2271,11 @@ PATTERNS
pat lae rck $2==4 /* Range check */ pat lae rck $2==4 /* Range check */
with REG with REG
uses CR0
gen gen
cmpli %a, {CONST, 0}, %1, {CONST, rom($1, 1)} cmpwi %1, {CONST, rom($1, 1)}
bc IFTRUE, LT, {LABEL, ".trap_erange"} blt {LABEL, ".trap_erange"}
cmpli %a, {CONST, 0}, %1, {CONST, rom($1, 2)} cmpwi %1, {CONST, rom($1, 2)}
bc IFTRUE, GT, {LABEL, ".trap_erange"} bgt {LABEL, ".trap_erange"}
yields %1 yields %1
@ -2132,7 +2329,60 @@ PATTERNS
pat cmf $1==INT32 /* Compare single */ pat cmf $1==INT32 /* Compare single */
with FSREG FSREG 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 */ pat loc loc cff $1==INT32 && $2==INT64 /* Convert single to double */
with FSREG with FSREG
@ -2206,7 +2456,60 @@ PATTERNS
pat cmf $1==INT64 /* Compare double */ pat cmf $1==INT64 /* Compare double */
with FREG FREG 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 */ pat loc loc cff $1==INT64 && $2==INT32 /* Convert double to single */
with FREG with FREG
@ -2238,14 +2541,14 @@ PATTERNS
pat fef $1==INT64 /* Split exponent, fraction */ pat fef $1==INT64 /* Split exponent, fraction */
with GPR3 GPR4 with GPR3 GPR4
kills FPR0, FPR1, GPR6, GPR7 kills ALL
gen gen
bl {LABEL, ".fef8"} bl {LABEL, ".fef8"}
yields R4 R3 R5 yields R4 R3 R5
pat fif $1==INT64 /* Multiply then split integer, fraction */ pat fif $1==INT64 /* Multiply then split integer, fraction */
with FPR1 FPR2 with FPR1 FPR2
kills FPR1, FPR2, GPR3, GPR4, GPR5, GPR6 kills ALL
gen gen
bl {LABEL, ".fif8"} bl {LABEL, ".fif8"}
yields F1 F2 yields F1 F2

View file

@ -6,15 +6,15 @@ LABEL_STARTER '.';
%%; %%;
P, Q, R { TRUE }; RNZ { strcmp(VAL, "r0") }; /* not r0 */
X, Y, Z { TRUE }; X, Y, Z { TRUE };
%%; %%;
/* Whitespace is significant here! */ /* Whitespace is significant here! */
addi X, X, 0 -> ; addi RNZ, RNZ, 0 -> ;
addis X, X, 0 -> ; addis RNZ, RNZ, 0 -> ;
mr X, X -> ; mr X, X -> ;
fmr X, X -> ; fmr X, X -> ;

View file

@ -0,0 +1,7 @@
#include <signal.h>
#include "libsys.h"
int sigprocmask(int flags, const sigset_t *new, sigset_t *old)
{
return _syscall(__NR_sigprocmask, flags, (quad) new, (quad) old);
}

View file

@ -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 off_t lseek(int fildes, off_t offset, int whence);
extern int fcntl(int fd, int op, ...); extern int fcntl(int fd, int op, ...);
extern int unlink(const char* path); extern int unlink(const char* path);
extern int remove(const char* path);
/* Special variables */ /* Special variables */
@ -117,8 +116,16 @@ typedef int sig_atomic_t;
#define _NSIG 32 /* Biggest signal number + 1 #define _NSIG 32 /* Biggest signal number + 1
(not including real-time signals). */ (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); typedef void (*sighandler_t)(int);
extern sighandler_t signal(int signum, sighandler_t handler); extern sighandler_t signal(int signum, sighandler_t handler);
extern int sigprocmask(int, const sigset_t *, sigset_t *);
extern int raise(int signum); extern int raise(int signum);

View file

@ -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 int write(int fd, void* buffer, size_t count);
extern off_t lseek(int fildes, off_t offset, int whence); extern off_t lseek(int fildes, off_t offset, int whence);
extern int fcntl(int fd, int op, ...); extern int fcntl(int fd, int op, ...);
extern int unlink(const char* path);
/* Special variables */ /* Special variables */
@ -67,6 +68,7 @@ extern pid_t getpid(void);
extern int brk(void* ptr); extern int brk(void* ptr);
extern void* sbrk(int increment); extern void* sbrk(int increment);
extern int isatty(int d); extern int isatty(int d);
extern int execve(const char *path, char *const argv[], char *const envp[]);
/* Signal handling */ /* Signal handling */
@ -114,8 +116,16 @@ typedef int sig_atomic_t;
#define _NSIG 32 /* Biggest signal number + 1 #define _NSIG 32 /* Biggest signal number + 1
(not including real-time signals). */ (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); typedef void (*sighandler_t)(int);
extern sighandler_t signal(int signum, sighandler_t handler); extern sighandler_t signal(int signum, sighandler_t handler);
extern int sigprocmask(int, const sigset_t *, sigset_t *);
extern int raise(int signum); extern int raise(int signum);

View file

@ -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 int write(int fd, void* buffer, size_t count);
extern off_t lseek(int fildes, off_t offset, int whence); extern off_t lseek(int fildes, off_t offset, int whence);
extern int fcntl(int fd, int op, ...); extern int fcntl(int fd, int op, ...);
extern int unlink(const char* path);
/* Special variables */ /* Special variables */
@ -115,8 +116,34 @@ typedef int sig_atomic_t;
#define _NSIG 32 /* Biggest signal number + 1 #define _NSIG 32 /* Biggest signal number + 1
(not including real-time signals). */ (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); typedef void (*sighandler_t)(int);
extern int sigaction(int, const struct sigaction *, struct sigaction *);
extern sighandler_t signal(int signum, sighandler_t handler); extern sighandler_t signal(int signum, sighandler_t handler);
extern int sigprocmask(int, const sigset_t *, sigset_t *);
extern int raise(int signum); extern int raise(int signum);

View file

@ -1,16 +1,36 @@
acklibrary { acklibrary {
name = "lib", name = "lib",
srcs = { srcs = {
"./*.s", "./_syscall.s",
"plat/linux/libsys/*.c", "./sigaction.s",
"plat/linux/libsys/*.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 = { deps = {
"lang/cem/libcc.ansi/headers+headers", "lang/cem/libcc.ansi/headers+headers",
"plat/linuxppc/include+headers", "plat/linuxppc/include+headers",
}, },
vars = { vars = {
plat = "linuxppc" plat = "linuxppc"
} }
} }

View file

@ -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

View file

@ -0,0 +1,19 @@
#include <signal.h>
/*
* 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;
}

View file

@ -107,14 +107,20 @@ static uint32_t get_vc4_valu(char* addr)
static bool is_powerpc_memory_op(uint32_t opcode) static bool is_powerpc_memory_op(uint32_t opcode)
{ {
/* Tests for any PowerPC memory indirection instruction where the payload /* Tests for any PowerPC memory indirection instruction (or
* is a *signed* 16-bit value. */ * addi) where the payload is a *signed* 16-bit value. */
switch ((opcode & 0xfc000000) >> 26) switch ((opcode & 0xfc000000) >> 26)
{ {
case 14: /* addi */
case 34: /* lbz */ case 34: /* lbz */
case 48: /* lfs */
case 50: /* lfd */
case 42: /* lha */
case 40: /* lhz */ case 40: /* lhz */
case 32: /* lwz */ case 32: /* lwz */
case 38: /* stb */ case 38: /* stb */
case 52: /* stfs */
case 54: /* stfd */
case 44: /* sth */ case 44: /* sth */
case 36: /* stw */ case 36: /* stw */
return true; return true;