diff options
Diffstat (limited to 'chapter21/src')
7 files changed, 61 insertions, 20 deletions
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/IntARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/IntARM.java index f9b53f6b..9f9c6db6 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/IntARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/IntARM.java @@ -20,10 +20,39 @@ public class IntARM extends ConstantNode implements MachNode { @Override public void encoding( Encoding enc ) { short self = enc.reg(this); long x = ((TypeInteger)_con).value(); - if( (short)x == x ) - enc.add4(arm.mov(485, 0, (int)(x&0xFFFF), self)); - else - throw Utils.TODO("Handle cases bigger than 16 bits"); + int nb0 = 0; + int nb1 = 0; + // Count number of 0000 and FFFF blocks + for (int i=0; i<64; i+=16) { + int block = (int)(x >> i) & 0xFFFF; + if (block == 0) nb0++; + if (block == 0xFFFF) nb1++; + } + int pattern; + int op; + if(nb0 >= nb1) { + // More 0 blocks then F blocks, use movz + pattern = 0; + op = 0b110100101; + } else { + // More F blocks then 0 blocks, use movn + pattern = 0xFFFF; + op = 0b100100101; + } + int invert = pattern; + for (int i=0; i<4; i++) { + int block = (int)x & 0xFFFF; + x >>= 16; + if (block != pattern) { + enc.add4(arm.mov(op, i, block ^ invert, self)); + op = 0b111100101; + invert = 0; + } + } + if (op != 0b111100101) { + // All blocks are the same, special case + enc.add4(arm.mov(op, 0, 0, self)); + } } // Human-readable form appended to the SB. Things like the encoding, diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/UJmpARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/UJmpARM.java index cc0b2085..e08010f4 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/UJmpARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/UJmpARM.java @@ -20,8 +20,7 @@ public class UJmpARM extends CFGNode implements MachNode { @Override public Node idealize() { throw Utils.TODO(); } @Override public void encoding( Encoding enc ) { enc.jump(this,uctrl()); - // TODO: unconditional jump - int body = arm.b_cond(0b01010100, 0, arm.make_condition("<")); + int body = arm.b(0b01010100, 0); enc.add4(body); } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java index c6bb1973..bff08458 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java @@ -252,7 +252,7 @@ public class arm extends Machine { enc.add4(body); } - // encodes movk + // encodes movk, movn, and movz public static int mov(int opcode, int shift, int imm16, int rd) { return (opcode << 23) | (shift << 21) | (imm16 << 5) | rd; } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/UJmpRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/UJmpRISC.java index bcffa544..cf330ed5 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/UJmpRISC.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/UJmpRISC.java @@ -19,9 +19,9 @@ public class UJmpRISC extends CFGNode implements MachNode { @Override public Type compute() { throw Utils.TODO(); } @Override public Node idealize() { throw Utils.TODO(); } @Override public void encoding( Encoding enc ) { + // jal enc.jump(this,uctrl()); - // TODO: Unconditional jump - int body = riscv.b_type(0x63, 0, riscv.jumpop("<"), 0, 0, 0); + int body = riscv.j_type(0b0110111, 0, 0); enc.add4(body); } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java index 08239288..aa5de1aa 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java @@ -131,7 +131,9 @@ public class riscv extends Machine { public static int u_type(int opcode, int rd, int imm20) { return (imm20 << 12) | (rd << 7) | opcode; } - + public static int j_type(int opcode, int rd, int imm20) { + return imm20 << 12 | rd << 7 | opcode; + } public static int i_type(int opcode, int rd, int func3, int rs1, int imm12) { assert opcode >= 0 && rd >=0 && func3 >=0 && rs1 >=0 && imm12 >= 0; // Zero-extend by caller return (imm12 << 20) | (rs1 << 15) | (func3 << 12) | (rd << 7) | opcode; diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/IntX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/IntX86.java index d9836e00..6d9110f2 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/IntX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/IntX86.java @@ -36,14 +36,27 @@ public class IntX86 extends ConstantNode implements MachNode { // Simply move the constant into a GPR // Conditional encoding based on 64 or 32 bits //REX.W + C7 /0 id MOV r/m64, imm32 - enc.add1(x86_64_v2.rex(0, dst, 0)); long imm = ((TypeInteger)_con).value(); - if( (int)imm == imm ) { + if (Integer.MIN_VALUE <= imm && imm < 0) { + // We need sign extension, so use imm32 into 64 bit register + // REX.W + C7 /0 id MOV r/m64, imm32 + enc.add1(x86_64_v2.rex(0, dst, 0)); enc.add1(0xC7); // 32 bits encoding enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, 0x00, dst)); enc.add4((int)imm); + } else if (0 <= imm && imm <= 0xFFFFFFFFL) { + // We want zero extension into 64 bit register + // so move 32 bit into 32 bit register which zeros + // the upper bits in the 64 bit register. + // B8+ rd id MOV r32, imm32 + if (dst >= 8) enc.add1(0x41); + enc.add1(0xB8 + (dst & 0x07)); + enc.add4((int)imm); } else { + // Just write the full 64 bit constant + // REX.W + B8+ rd io MOV r64, imm64 + enc.add1(x86_64_v2.rex(0, dst, 0)); enc.add1(0xB8 + (dst & 0x07)); enc.add8(imm); // 64 bits encoding } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TFPX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TFPX86.java index 4167962b..a80531b6 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TFPX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/TFPX86.java @@ -33,15 +33,13 @@ public class TFPX86 extends ConstantNode implements MachNode { return; } + // lea to load function pointer address + // lea rax, [rip+disp32] enc.relo(this,(TypeFunPtr)_con); - // Simply move the constant into a GPR - // Conditional encoding based on 64 or 32 bits - //REX.W + C7 /0 id MOV r/m64, imm32 - enc.add1(x86_64_v2.rex(0, dst, 0)); - enc.add1(0xC7); // 32 bits encoding - enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, 0x00, dst)); - //enc.add4((int)imm); - throw Utils.TODO(); + enc.add1(x86_64_v2.rex(dst, 0, 0)); + enc.add1(0x8D); // opcode + enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.INDIRECT, dst, 0b101)); + enc.add4(0); } // Human-readable form appended to the SB. Things like the encoding, |
