[PowerPC] Various SLEIGH fixes

- Ensure registers do not overlap for source and destination registers
- preserve register values when needed
- signed issue comparing unsigned to negative
- unued argument in divZero macro
- stwcx. and stdcx. should set cr bits to continue
- out of order flag setting vs value assignment
- some fixes in setting wrong cr bit
This commit is contained in:
mumbel 2021-06-25 10:52:06 -05:00
parent ecef7844fd
commit d61be26b38
5 changed files with 406 additions and 275 deletions

View file

@ -1561,9 +1561,12 @@ macro setCrBit(crReg, bitIndex, bit)
crReg = crReg | tmp;
}
macro cr0flags(result ) {
setCrBit(cr0, 0, (result s< 0));
setCrBit(cr0, 1, (result s> 0));
setCrBit(cr0, 2, (result == 0));
# the first three bits of CR are set by signed comparison of the
# result to zero, and the fourth bit of CR is copied from the SO field
# of the XER
setCrBit(cr0, 0, (result s< 0)); # 0b100
setCrBit(cr0, 1, (result s> 0)); # 0b010
setCrBit(cr0, 2, (result == 0)); # 0b001
setCrBit(cr0, 3, (xer_so & 1));
}
@ -1586,7 +1589,7 @@ macro divOverflow(a,b) {
xer_ov = (b==0) || ((b==-1) && (a==0x80000000));
xer_so = xer_so || xer_ov;
}
macro divZero(a,b) {
macro divZero(b) {
xer_ov = (b==0);
xer_so = xer_so || xer_ov;
}

View file

@ -352,9 +352,8 @@ define pcodeop AddAndGenerateSixes;
# C low 4 bytes to TH high 4 bytes
tmp = zext(c);
tmp = tmp << 32;
TH = tmp;
divOverflow(A,B);
TH = tmp;
}
# PowerISA II: 3.3.8 Fixed-Point Arithmetic Instructions
@ -380,9 +379,9 @@ define pcodeop DivideWordExtended4;
# C low 4 bytes to TH high 4 bytes
tmp = zext(c);
tmp = tmp << 32;
divOverflow(A,B);
TH = tmp;
divOverflow(A,B);
cr0flags(TH);
}
@ -460,9 +459,8 @@ define pcodeop DivideWordExtended4;
# C low 4 bytes to TH high 4 bytes
tmp = zext(c);
tmp = tmp << 32;
TH = tmp;
divOverflow(A,B);
TH = tmp;
}
# PowerISA II: 3.3.8 Fixed-Point Arithmetic Instructions
@ -487,9 +485,9 @@ define pcodeop DivideWordExtended4;
# C low 4 bytes to TH high 4 bytes
tmp = zext(c);
tmp = tmp << 32;
divOverflow(A,B);
TH = tmp;
divOverflow(A,B);
cr0flags(TH);
}
@ -1683,16 +1681,16 @@ define pcodeop eieioOp;
# binutils-descr: "divdeuo", XO(31,393,1,0), XO_MASK, POWER7|PPCA2, PPCNONE, {RT, RA, RB}
# binutils: mytest.d: 28: 7c 64 2f 12 divdeuo r3,r4,r5
:divdeuo RT,A,B is $(NOTVLE) & OP=31 & XOP_1_9=393 & OE=1 & Rc=0 & RT & A & B {
RT = A/B;
divOverflow(A,B);
RT = A/B;
}
# binutils-descr: "divdeuo.", XO(31,393,1,1), XO_MASK, POWER7|PPCA2, PPCNONE, {RT, RA, RB}
define pcodeop divdeuoDotOp;
# binutils: mytest.d: 2c: 7c 64 2f 13 divdeuo. r3,r4,r5
:divdeuo. RT,A,B is $(NOTVLE) & OP=31 & XOP_1_9=393 & OE=1 & Rc=1 & RT & A & B {
RT = A/B;
divOverflow(A,B);
RT = A/B;
cr0flags(RT);
}
@ -1726,16 +1724,16 @@ define pcodeop stfddxOp;
define pcodeop divdeoOp;
# binutils: mytest.d: 38: 7c 64 2f 52 divdeo r3,r4,r5
:divdeo RT,A,B is $(NOTVLE) & OP=31 & XOP_1_9=425 & OE=1 & Rc=0 & RT & A & B {
RT = A s/ B;
divOverflow(A,B);
RT = A s/ B;
}
# binutils-descr: "divdeo.", XO(31,425,1,1), XO_MASK, POWER7|PPCA2, PPCNONE, {RT, RA, RB}
define pcodeop divdeoDotOp;
# binutils: mytest.d: 3c: 7c 64 2f 53 divdeo. r3,r4,r5
:divdeo. RT,A,B is $(NOTVLE) & OP=31 & XOP_1_9=425 & OE=1 & Rc=1 & RT & A & B {
RT = A s/ B;
divOverflow(A,B);
RT = A s/ B;
cr0flags(RT);
}
@ -2574,10 +2572,12 @@ define pcodeop InstructionCacheBlockLockSetX;
:cmpeqb CRFD,A,B is $(NOTVLE) & OP=31 & BITS_21_22=0 & BIT_0=0 & XOP_1_10=224 & A & B & CRFD {
tmpa:1 = A:1;
CRFD = (tmpa == B[0,8]) | (tmpa == B[8,8]) | (tmpa == B[16,8]) | (tmpa == B[24,8]);
match:1 = (tmpa == B[0,8]) | (tmpa == B[8,8]) | (tmpa == B[16,8]) | (tmpa == B[24,8]);
@if REGISTER_SIZE == "8"
CRFD = CRFD | (tmpa == B[32,8]) | (tmpa == B[40,8]) | (tmpa == B[48,8]) | (tmpa == B[56,8]);
match = match | (tmpa == B[32,8]) | (tmpa == B[40,8]) | (tmpa == B[48,8]) | (tmpa == B[56,8]);
@endif
# 0b0 | match | 0b0 | 0b0
CRFD = (match & 1) << 2;
}
:cmprb CRFD,L2,A,B is $(NOTVLE) & OP=31 & BIT_22=0 & BIT_0=0 & XOP_1_10=192 & A & B & CRFD & L2 {
@ -2586,7 +2586,9 @@ define pcodeop InstructionCacheBlockLockSetX;
tmp1hi:1 = B[24,8];
tmp2lo:1 = B[0,8];
tmp2hi:1 = B[8,8];
CRFD = ((tmpin >= tmp2lo) & (tmpin <= tmp2hi)) | (((tmpin >= tmp1lo) & (tmpin <= tmp1hi)) * L2:1);
in_range:1 = ((tmpin >= tmp2lo) & (tmpin <= tmp2hi)) | (((tmpin >= tmp1lo) & (tmpin <= tmp1hi)) * L2:1);
# 0b0 | in_range | 0b0 | 0b0
CRFD = (in_range & 1) << 2;
}
:cnttzw A,S is OP=31 & S & A & BITS_11_15=0 & XOP_1_10=538 & Rc=0 {

View file

@ -215,8 +215,9 @@ IMM16B: val is IMM_0_10_VLE & IMM_16_20_VLE [ val = (IMM_16_20_VLE << 11) |
:e_lbzu D,d8PlusRaAddress is $(ISVLE) & OP=6 & D & A & XOP_8_VLE=0 & d8PlusRaAddress
{
D = zext(*:1(d8PlusRaAddress));
A = d8PlusRaAddress;
ea:$(REGISTER_SIZE) = d8PlusRaAddress;
D = zext(*:1(ea));
A = ea;
}
# e_ldmvcsrrw 6 (0b0001_10) 0b00101 RA 0b0001_0000 D8
@ -299,14 +300,16 @@ IMM16B: val is IMM_0_10_VLE & IMM_16_20_VLE [ val = (IMM_16_20_VLE << 11) |
:e_lhau D,d8PlusRaAddress is $(ISVLE) & OP=6 & D & A & XOP_8_VLE=3 & d8PlusRaAddress
{
D = sext(*:2(d8PlusRaAddress));
A = d8PlusRaAddress;
ea:$(REGISTER_SIZE) = d8PlusRaAddress;
D = sext(*:2(ea));
A = ea;
}
:e_lhzu D,d8PlusRaAddress is $(ISVLE) & OP=6 & D & A & XOP_8_VLE=1 & d8PlusRaAddress
{
D = zext(*:2(d8PlusRaAddress));
A = d8PlusRaAddress;
ea:$(REGISTER_SIZE) = d8PlusRaAddress;
D = zext(*:2(ea));
A = ea;
}
:e_lwz D,dPlusRaOrZeroAddress is $(ISVLE) & OP=20 & D & dPlusRaOrZeroAddress
@ -320,8 +323,9 @@ IMM16B: val is IMM_0_10_VLE & IMM_16_20_VLE [ val = (IMM_16_20_VLE << 11) |
:e_lwzu D,d8PlusRaAddress is $(ISVLE) & OP=6 & D & A & XOP_8_VLE=2 & d8PlusRaAddress
{
D = zext(*:4(d8PlusRaAddress));
A = d8PlusRaAddress;
ea:$(REGISTER_SIZE) = d8PlusRaAddress;
D = zext(*:4(ea));
A = ea;
}
:e_stb S,dPlusRaOrZeroAddress is $(ISVLE) & OP=13 & S & dPlusRaOrZeroAddress
@ -335,8 +339,9 @@ IMM16B: val is IMM_0_10_VLE & IMM_16_20_VLE [ val = (IMM_16_20_VLE << 11) |
:e_stbu S,d8PlusRaAddress is $(ISVLE) & OP=6 & XOP_8_VLE=4 & S & A & d8PlusRaAddress
{
*:1(d8PlusRaAddress) = S:1;
A = d8PlusRaAddress;
ea:$(REGISTER_SIZE) = d8PlusRaAddress;
*:1(ea) = S:1;
A = ea;
}
:e_sth S,dPlusRaOrZeroAddress is $(ISVLE) & OP=23 & S & dPlusRaOrZeroAddress
@ -350,8 +355,9 @@ IMM16B: val is IMM_0_10_VLE & IMM_16_20_VLE [ val = (IMM_16_20_VLE << 11) |
:sthu S,d8PlusRaAddress is $(ISVLE) & OP=6 & XOP_8_VLE=5 & S & A & d8PlusRaAddress
{
*:2(d8PlusRaAddress) = S:2;
A = d8PlusRaAddress;
ea:$(REGISTER_SIZE) = d8PlusRaAddress;
*:2(ea) = S:2;
A = ea;
}
# e_stmvcsrrw 6 (0b0001_10) 0b00101 RA 0b0001_0001 D8
@ -436,12 +442,13 @@ IMM16B: val is IMM_0_10_VLE & IMM_16_20_VLE [ val = (IMM_16_20_VLE << 11) |
:e_stwu S,d8PlusRaAddress is $(ISVLE) & OP=6 & XOP_8_VLE=6 & S & A & d8PlusRaAddress
{
ea:$(REGISTER_SIZE) = d8PlusRaAddress;
@ifdef BIT_64
*:4(d8PlusRaAddress) = S:4;
*:4(ea) = S:4;
@else
*:4(d8PlusRaAddress) = S;
*:4(ea) = S;
@endif
A = d8PlusRaAddress;
A = ea;
}
:e_lmw D,d8PlusRaOrZeroAddress is $(ISVLE) & OP=6 & XOP_8_VLE=8 & D & BITS_21_25 & d8PlusRaOrZeroAddress & LDMR31 [ lsmul = BITS_21_25; ]

View file

@ -63,9 +63,10 @@ define pcodeop invalidateTLB;
:isel^CC_X_OPm D,RA_OR_ZERO,B,CC_X_OP is OP=31 & D & RA_OR_ZERO & B & CC_X_OP & CC_X_OPm & XOP_1_5=15
{
D = B;
if (!CC_X_OP) goto inst_next;
D = RA_OR_ZERO;
local tmp:$(REGISTER_SIZE) = RA_OR_ZERO;
D = B;
if (!CC_X_OP) goto inst_next;
D = tmp;
# D = (zext(CC_X_OP) * RA_OR_ZERO) + (zext(!CC_X_OP) * B);
}