diff options
Diffstat (limited to 'chapter21/src/test/java/com/seaofnodes')
| -rw-r--r-- | chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java | 17 | ||||
| -rw-r--r-- | chapter21/src/test/java/com/seaofnodes/simple/EvalArm64.java | 22 |
2 files changed, 27 insertions, 12 deletions
diff --git a/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java b/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java index 72041bd7..6c943904 100644 --- a/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java +++ b/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java @@ -11,6 +11,23 @@ import org.junit.Test; import static org.junit.Assert.*; public class Chapter21Test { + + @Test public void testArmBitfieldExtracts() { + // Independent SXT/UXT instruction words, plus ASR, LSR and LSL aliases. + int[] ops = {0x93401c20,0xd3401c20,0x93403c20,0xd3403c20, + 0x93407c20,0xd3407c20,0x9344fc20,0xd344fc20,0xd37cec20}; + long value = 0xa5a5a5a580008080L; + long[] expected = {(byte)value,value&255,(short)value,value&65535, + (int)value,value&0xffffffffL,value>>4,value>>>4,value<<4}; + for( int i=0; i<ops.length; i++ ) { + EvalArm64 cpu = new EvalArm64(new byte[1<<16],1<<15); + cpu.st4(0,ops[i]); cpu.regs[1]=value; + assertEquals(0,cpu.step(1)); + assertEquals(expected[i],cpu.regs[0]); + } + } + + @Test public void testReturnedFunctionEncoding() throws IOException { String src = "if(arg) return {->42;}; return {->43;};"; CodeGen code = new CodeGen(src).driver("riscv","SystemV",null); diff --git a/chapter21/src/test/java/com/seaofnodes/simple/EvalArm64.java b/chapter21/src/test/java/com/seaofnodes/simple/EvalArm64.java index 75525133..e5aa729b 100644 --- a/chapter21/src/test/java/com/seaofnodes/simple/EvalArm64.java +++ b/chapter21/src/test/java/com/seaofnodes/simple/EvalArm64.java @@ -641,20 +641,18 @@ public class EvalArm64 { rval = opcode1==0x91 ? regs[rn] + immediate : regs[rn] - immediate; break; } - case 0xD3: { - // lsl(immediate) - int imm = (ir >> 16) & 0x3F; - int rn = (ir >> 5) & 0x1F; - rval = regs[rn] << (64 - imm); - break; - } - case 0x93: { - // asr(immediate) - int imm = (ir >> 16) & 0x3F; - int rn = (ir >> 5) & 0x1F; - rval = regs[rn] >> (imm); + case 0x93, 0xD3: { // SBFM/UBFM: shifts and signed/unsigned extracts + int immr = (ir >>> 16) & 63; + int imms = (ir >>> 10) & 63; + int rn = (ir >>> 5) & 31; + boolean signed = (ir & 0x40000000)==0; + long value = regs[rn] << (63-imms); + value = signed ? value >> (63-imms) : value >>> (63-imms); + rval = immr > imms ? value << (64-immr) + : signed ? value >> immr : value >>> immr; break; } + case 0x92: { // and(immediate) int imm12 = (ir >> 10) & 0x1FFF; |
