summaryrefslogtreecommitdiff
path: root/isa
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2026-10-07 21:31:18 -0700
committerCliff Click <cliffc@acm.org>2026-10-07 21:31:18 -0700
commit87a75c83b75480e65147a4d425fddd14a05df4d9 (patch)
treef486050aa3a13e218ad17ab57efaccbe35336483 /isa
parent2eba63966bdc3d9cfdf41ee085f35cbb6d529bbc (diff)
downloadSimple-87a75c83b75480e65147a4d425fddd14a05df4d9.tar.gz
Simple-87a75c83b75480e65147a4d425fddd14a05df4d9.zip
More test case vs RA cleanup
Missing a few risc/arm encodings. Make private many tests, so they don't escape and the escaped fcn inflate x86 spill numbers
Diffstat (limited to 'isa')
-rw-r--r--isa/src/test-support/java/com/seaofnodes/isa/eval/EvalArm64.java16
-rw-r--r--isa/src/test-support/java/com/seaofnodes/isa/eval/EvalRisc5.java17
-rw-r--r--isa/src/test/java/com/seaofnodes/isa/RiscTest.java41
3 files changed, 69 insertions, 5 deletions
diff --git a/isa/src/test-support/java/com/seaofnodes/isa/eval/EvalArm64.java b/isa/src/test-support/java/com/seaofnodes/isa/eval/EvalArm64.java
index 2fa4aec1..1ff77f59 100644
--- a/isa/src/test-support/java/com/seaofnodes/isa/eval/EvalArm64.java
+++ b/isa/src/test-support/java/com/seaofnodes/isa/eval/EvalArm64.java
@@ -329,6 +329,11 @@ public class EvalArm64 {
rval = regs[rn] & immediate;
break;
}
+ case 0xB2: { // ORR (immediate)
+ int rn = (ir >>> 5) & 31;
+ rval = (rn==31 ? 0 : regs[rn]) | Arm64.decodeImm12((ir >>> 10) & 0x1FFF);
+ break;
+ }
case 0x93, 0xD3: { // SBFM/UBFM: shifts and signed/unsigned extracts
int immr = (ir >>> 16) & 63;
int imms = (ir >>> 10) & 63;
@@ -372,6 +377,12 @@ public class EvalArm64 {
}
case 0x9A: {
+ if( (ir & 0xFFE0FC00)==0x9AC00C00 ) { // SDIV Xd,Xn,Xm
+ int rn=(ir >>> 5)&31, rm=(ir >>> 16)&31;
+ long lhs=rn==31 ? 0 : regs[rn], rhs=rm==31 ? 0 : regs[rm];
+ rval = rhs==0 ? 0 : lhs/rhs;
+ break;
+ }
int encodedCond = (ir >> 12) & 0xF;
int decodedCond = encodedCond ^ 1;
// conditional select(csel)
@@ -394,7 +405,7 @@ public class EvalArm64 {
case 0xF -> false ; // never
default -> throw new UnsupportedOperationException();
};
- if( cond ) rval = 1;
+ rval = cond ? 1 : 0;
break;
}
case 0x9B: { // mul
@@ -761,7 +772,8 @@ public class EvalArm64 {
}
if(rdid != -1) {
if(is_f) fregs[rdid] = frval;
- else regs[rdid] = rval;
+ // Register 31 is XZR except for ADD/SUB immediate, which writes SP.
+ else if( rdid!=31 || opcode1==0x91 || opcode1==0xD1 ) regs[rdid] = rval;
}
pc += 4;
diff --git a/isa/src/test-support/java/com/seaofnodes/isa/eval/EvalRisc5.java b/isa/src/test-support/java/com/seaofnodes/isa/eval/EvalRisc5.java
index 46baf447..e6860ccd 100644
--- a/isa/src/test-support/java/com/seaofnodes/isa/eval/EvalRisc5.java
+++ b/isa/src/test-support/java/com/seaofnodes/isa/eval/EvalRisc5.java
@@ -203,6 +203,17 @@ public class EvalRisc5 {
break;
}
+ case 0x27: { // FSW/FSD
+ int rs1=(int)regs[(ir >>> 15)&31], rs2=(ir >>> 20)&31;
+ int addr=rs1+((ir >> 25)<<5)+((ir >>> 7)&31);
+ switch((ir >>> 12)&7) {
+ case 2: st4(addr,Float.floatToRawIntBits((float)fregs[rs2])); break;
+ case 3: st8(addr,Double.doubleToRawLongBits(fregs[rs2])); break;
+ default: trap=3;
+ }
+ rdid=0;
+ break;
+ }
case 0x23: { // Store 0b0100011
int rs1 = (int)regs[(ir >> 15) & 0x1f]; // Address chop to 32b
long rs2 = regs[(ir >> 20) & 0x1f];
@@ -252,7 +263,7 @@ public class EvalRisc5 {
case 0 -> (is_reg && (ir & 0x40000000) != 0) ? (rs1 - rs2) : (rs1 + rs2);
case 1 -> rs1 << (rs2 & 0x3F);
case 2 -> (rs1 < rs2) ? 1 : 0;
- case 3 -> (rs1 < rs2) ? 1 : 0;
+ case 3 -> Long.compareUnsigned(rs1,rs2)<0 ? 1 : 0;
case 4 -> rs1 ^ rs2;
case 5 -> (ir & 0x40000000) != 0 ? (rs1 >> (rs2 & 0x3F)) : (rs1 >>> (rs2 & 0x3F));
case 6 -> rs1 | rs2;
@@ -329,8 +340,8 @@ public class EvalRisc5 {
is_f = false; // Output into a GPR
rval = switch( (ir >> 12) & 7 ) {
case 0 -> lhs <= rhs ? 1 : 0;
- case 1 -> lhs == rhs ? 1 : 0;
- case 2 -> lhs < rhs ? 1 : 0;
+ case 1 -> lhs < rhs ? 1 : 0;
+ case 2 -> lhs == rhs ? 1 : 0;
default -> throw new UnsupportedOperationException();
};
break;
diff --git a/isa/src/test/java/com/seaofnodes/isa/RiscTest.java b/isa/src/test/java/com/seaofnodes/isa/RiscTest.java
index 0cef8531..d10f97a4 100644
--- a/isa/src/test/java/com/seaofnodes/isa/RiscTest.java
+++ b/isa/src/test/java/com/seaofnodes/isa/RiscTest.java
@@ -9,6 +9,47 @@ public class RiscTest {
assert expected==actual : String.format("Expected %08x, got %08x",expected,actual);
}
public static void main(String[] args) {
+ // Instructions encountered by dynamic allocation measurements.
+ for( long[] pair : new long[][]{{17,3},{-17,3},{17,0},{Long.MIN_VALUE,-1}} ) {
+ var a=new EvalArm64(new byte[1024],512);
+ a.st4(4,0x9AC20C20); // sdiv x0,x1,x2
+ a._pc=4;a.regs[1]=pair[0];a.regs[2]=pair[1];
+ assert a.step(1)==0;
+ assert a.regs[0]==(pair[1]==0 ? 0 : pair[0]/pair[1]);
+ }
+ var discard=new EvalArm64(new byte[1024],512);
+ discard.st4(4,0x3862683F); // ldrb wzr,[x1,x2]; discard without changing SP
+ discard._pc=4;discard.regs[1]=100;discard.regs[2]=4;discard.st1(104,91);
+ assert discard.step(1)==0 && discard.regs[31]==512;
+ for(long value:new long[]{-1,0,1,Long.MIN_VALUE}) {
+ var unsigned=new EvalRisc5(new byte[1024],512);
+ unsigned.st4(4,0x00113193); // sltiu x3,x2,1 (seqz)
+ unsigned._pc=4;unsigned.regs[2]=value;
+ assert unsigned.step(1)==0;
+ assert unsigned.regs[3]==(value==0 ? 1 : 0);
+ }
+ var logical=new EvalArm64(new byte[1024],512);
+ logical.st4(4,0xB27F0020); // orr x0,x1,#2
+ logical.st4(8,0x9A9F17E2); // cset x2,eq; false must not retain prior result
+ logical._pc=4;logical.regs[1]=8;
+ assert logical.step(2)==0;
+ assert logical.regs[0]==10 && logical.regs[2]==0;
+ for(double rhs:new double[]{1,2,3,Double.NaN}) {
+ var r=new EvalRisc5(new byte[1024],512);
+ r.st4(4,0xA220A1D3); // feq.d x3,f1,f2
+ r.st4(8,0xA2209253); // flt.d x4,f1,f2
+ r._pc=4;r.fregs[1]=2;r.fregs[2]=rhs;
+ assert r.step(2)==0;
+ assert r.regs[3]==(2==rhs ? 1 : 0);
+ assert r.regs[4]==(2<rhs ? 1 : 0);
+ }
+ var store=new EvalRisc5(new byte[1024],512);
+ store.st4(4,0x00113827); // fsd f1,16(sp)
+ store.st4(8,0xFE112E27); // fsw f1,-4(sp)
+ store._pc=4;store.fregs[1]=-3.25;
+ assert store.step(2)==0;
+ assert store.ld8(528)==Double.doubleToRawLongBits(-3.25);
+ assert store.ld4s(508)==Float.floatToRawIntBits(-3.25f);
word(0x9E780020,Arm64.floatToInteger(1,0)); // FCVTZS x0,d1
for( double value : new double[]{0.0,-0.0,6.92,-6.92,0.99,-0.99,
0x1p63,Math.nextDown(0x1p63),-0x1p63,Math.nextDown(-0x1p63),