diff options
Diffstat (limited to 'chapter21/src')
42 files changed, 180 insertions, 70 deletions
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddIARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddIARM.java index fab40b1d..443320f0 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddIARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AddIARM.java @@ -17,7 +17,9 @@ public class AddIARM extends MachConcreteNode implements MachNode { @Override public RegMask regmap(int i) { return arm.RMASK; } @Override public RegMask outregmap() { return arm.RMASK; } //ADD (immediate) - @Override public void encoding( Encoding enc ) { arm.imm_inst(enc,this,0b1001000100,_imm); } + @Override public void encoding( Encoding enc ) { + arm.imm_inst(enc,this,0b1001000100,_imm); + } // General form: "addi rd = rs1 + imm" @Override public void asm(CodeGen code, SB sb) { sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" + #").p(_imm); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndIARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndIARM.java index ce270356..12d7d7c5 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndIARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AndIARM.java @@ -14,7 +14,9 @@ public class AndIARM extends MachConcreteNode implements MachNode { @Override public String op() { return "andi"; } @Override public RegMask regmap(int i) { return arm.RMASK; } @Override public RegMask outregmap() { return arm.RMASK; } - @Override public void encoding( Encoding enc ) { arm.imm_inst(enc,this,0b100100100,_imm); } + @Override public void encoding( Encoding enc ) { + arm.imm_inst_n(enc,this,0b100100100,_imm); + } // General form: "andi rd = rs1 & imm" @Override public void asm(CodeGen code, SB sb) { sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" & #").p(_imm); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrIARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrIARM.java index e5636bc3..3371d3d2 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrIARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/AsrIARM.java @@ -22,7 +22,7 @@ public class AsrIARM extends MachConcreteNode implements MachNode { short rd = enc.reg(this); short rn = enc.reg(in(1)); assert _imm > 0; - enc.add4(arm.imm_shift(0b100100110,_imm, 0b111111, rn, rd)); + enc.add4(arm.imm_shift(0b1001001101,_imm, 0b111111, rn, rd)); } // General form: "asri rd = rs1 >> imm" @Override public void asm(CodeGen code, SB sb) { diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LoadARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LoadARM.java index 800ad34c..1c3e2e49 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LoadARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LoadARM.java @@ -4,6 +4,7 @@ import com.seaofnodes.simple.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.LoadNode; import com.seaofnodes.simple.node.Node; +import com.seaofnodes.simple.type.TypeFloat; // Load memory addressing on ARM // Support imm, reg(direct), or reg+off(indirect) addressing @@ -18,7 +19,13 @@ public class LoadARM extends MemOpARM{ @Override public String op() { return "ld"+_sz; } @Override public RegMask outregmap() { return arm.MEM_MASK; } // ldr(immediate - unsigned offset) | ldr(register) - @Override public void encoding( Encoding enc ) { ldst_encode(enc,0b11111000010,this); } + @Override public void encoding( Encoding enc ) { + if(_declaredType == TypeFloat.F32 || _declaredType == TypeFloat.F64) { + ldst_encode(enc, 0b1111110101, 0b11111100011, this, true); + } else { + ldst_encode(enc, 0b1111100101, 0b11111000011, this, false); + } + } @Override public void asm(CodeGen code, SB sb) { sb.p(code.reg(this)).p(","); asm_address(code,sb); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslIARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslIARM.java index d6633e51..3a7fc76c 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslIARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LslIARM.java @@ -24,7 +24,7 @@ public class LslIARM extends MachConcreteNode implements MachNode { assert _imm > 0; // UBFM <Xd>, <Xn>, #(-<shift> MOD 64), #(63-<shift>) // immr must be (-<shift> MOD 64) = 64 - shift - enc.add4(arm.imm_shift(0b110100110, 64 - _imm, (64 - _imm) - 1, rn, rd)); + enc.add4(arm.imm_shift(0b1101001101, 64 - _imm, (64 - _imm) - 1, rn, rd)); } // General form: "lsli rd = rs1 << imm" @Override public void asm(CodeGen code, SB sb) { diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrIARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrIARM.java index 8bf2b9ce..7b9241d0 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrIARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/LsrIARM.java @@ -20,7 +20,7 @@ public class LsrIARM extends MachConcreteNode implements MachNode { short rd = enc.reg(this); short rn = enc.reg(in(1)); assert _imm > 0; - enc.add4(arm.imm_shift(0b110100110,_imm, 0b111111, rn,rd)); + enc.add4(arm.imm_shift(0b1101001101,_imm, 0b111111, rn,rd)); } // General form: "lsri rd = rs1 >>> imm" @Override public void asm(CodeGen code, SB sb) { diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/MemOpARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/MemOpARM.java index 48e11522..ff3c41c3 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/MemOpARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/MemOpARM.java @@ -47,14 +47,14 @@ public abstract class MemOpARM extends MemOpNode implements MachNode { throw Utils.TODO(); } - // Shared encoding for loads and stores - public void ldst_encode( Encoding enc, int opcode, Node xval ) { + // Shared encoding for loads and stores(int and float) + public void ldst_encode( Encoding enc, int opcode_imm, int opcode_reg, Node xval, boolean float_type ) { short ptr = enc.reg(ptr()); short off = enc.reg(off()); - short val = enc.reg(xval ); + short val = enc.reg(xval); int body = off() == null - ? arm.load_str_imm(opcode, off, ptr, val) - : arm.indr_adr(opcode+1, off, arm.STORE_LOAD_OPTION.SXTX, 0, ptr, val); + ? arm.load_str_imm(opcode_imm, _off, ptr, val) + : arm.indr_adr(opcode_reg, off, arm.STORE_LOAD_OPTION.SXTX, 0, ptr, val); enc.add4(body); } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrIARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrIARM.java index bb28acdb..afd44306 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrIARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/OrIARM.java @@ -14,7 +14,9 @@ public class OrIARM extends MachConcreteNode implements MachNode { @Override public String op() { return "ori"; } @Override public RegMask regmap(int i) { return arm.RMASK; } @Override public RegMask outregmap() { return arm.RMASK; } - @Override public void encoding( Encoding enc ) { arm.imm_inst(enc,this,0b101100100,_imm); } + @Override public void encoding( Encoding enc ) { + arm.imm_inst_n(enc, this, 0b101100100, _imm); + } // General form: "ori rd = rs1 | imm" @Override public void asm(CodeGen code, SB sb) { sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" | #").p(_imm); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SplitARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SplitARM.java index f3ef7f7b..b52533e0 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SplitARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/SplitARM.java @@ -1,8 +1,10 @@ package com.seaofnodes.simple.node.cpus.arm; +import com.seaofnodes.simple.Utils; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.Node; import com.seaofnodes.simple.node.SplitNode; +import com.seaofnodes.simple.node.cpus.riscv.riscv; public class SplitARM extends SplitNode { SplitARM(String kind, byte round) { super(kind,round,new Node[2]);} @@ -10,9 +12,43 @@ public class SplitARM extends SplitNode { @Override public RegMask outregmap() { return arm.SPLIT_MASK; } @Override public void encoding( Encoding enc ) { - short self = enc.reg(this ); - short reg1 = enc.reg(in(1)); - int body = arm.r_reg(0b10101010, 0, reg1, 0, 31, self); - enc.add4(body); + short dst = enc.reg(this ); + short src = enc.reg(in(1)); + + boolean dstX = dst >= arm.D_OFFSET; + boolean srcX = src >= arm.D_OFFSET; + + if (dst >= arm.MAX_REG) { + // store to sp + if(src >= arm.MAX_REG) { + throw Utils.TODO(); + } + int off = enc._fun.computeStackSlot(dst - arm.MAX_REG)*8; + enc.add4(arm.load_str_imm(0b1111100100, off, src, dst)); + } + + if(src >= arm.MAX_REG) { + // Load from SP + int off = enc._fun.computeStackSlot(src - arm.MAX_REG) * 8; + enc.add4(arm.load_str_imm(0b1111100101, off, src, dst)); + } + + // pick opcode based on regs + if(!dstX && !srcX) { + // GPR->GPR + enc.add4(arm.mov_reg(0b10101010000, src, dst)); + } else if(dstX && srcX) { + // FPR->FPR + // fmov reg + enc.add4(arm.f_mov_reg(0b00011110, src,dst)); + } else if(dstX && !srcX) { + // GPR->FPR + // FMOV(general) 64 bits to DOUBLE-PRECISION + enc.add4(arm.f_mov_general(0b10011110, 0b01, 0, 0b111, src, dst)); + } else if(!dstX && srcX) { + //FPF->GPR + // FMOV(general) DOUBLE-PRECISION to 64 bits + enc.add4(arm.f_mov_general(0b10011110, 0b01, 0, 0b110, src, dst)); + } } } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/StoreARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/StoreARM.java index e1fb592c..97ee6bb2 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/StoreARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/StoreARM.java @@ -4,6 +4,7 @@ import com.seaofnodes.simple.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.StoreNode; import com.seaofnodes.simple.node.Node; +import com.seaofnodes.simple.type.TypeFloat; // Store memory addressing on ARM // Support imm, reg(direct), or reg+off(indirect) addressing @@ -21,7 +22,13 @@ public class StoreARM extends MemOpARM { } @Override public String op() { return "st"+_sz; } @Override public RegMask outregmap() { return null; } - @Override public void encoding( Encoding enc ) { ldst_encode(enc,0b11111000000, val()); } + @Override public void encoding( Encoding enc ) { + if(_declaredType == TypeFloat.F32 || _declaredType == TypeFloat.F64) { + ldst_encode(enc, 0b1111110100,0b11111100001, val(), true); + } else { + ldst_encode(enc, 0b1111100100, 0b11111000001, val(), false); + } + } @Override public void asm(CodeGen code, SB sb) { asm_address(code,sb).p(","); if( val()==null ) sb.p("#").p(_imm); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorIARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorIARM.java index 4814a7cc..429cdb38 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorIARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/XorIARM.java @@ -20,7 +20,7 @@ public class XorIARM extends MachConcreteNode implements MachNode { @Override public RegMask outregmap() { return arm.RMASK; } // General form: "xori rd = rs1 ^ imm" - @Override public void encoding( Encoding enc ) { arm.imm_inst(enc,this,0b110100100,_imm); } + @Override public void encoding( Encoding enc ) { arm.imm_inst_n(enc,this,0b110100100,_imm); } @Override public void asm(CodeGen code, SB sb) { sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" ^ #").p(_imm); } 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 4b0781f2..4c3b3fc7 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 @@ -27,6 +27,7 @@ public class arm extends Machine { static final int D16 = 48, D17 = 49, D18 = 50, D19 = 51, D20 = 52, D21 = 53, D22 = 54, D23 = 55; static final int D24 = 56, D25 = 57, D26 = 58, D27 = 59, D28 = 60, D29 = 61, D30 = 62, D31 = 63; + static final int MAX_REG = 64; static final int D_OFFSET = 31; static final int FLAGS = 64; @@ -210,11 +211,11 @@ public class arm extends Machine { // sh is encoded in opcdoe public static int imm_inst(int opcode, int imm12, int rn, int rd) { assert opcode >=0 && imm12 >= 0 && rn >=0 && rd>=0; // Caller zeros high order bits - return (opcode << 23) | (imm12 << 10) | (rn << 5) | rd; + return (opcode << 22) | (imm12 << 10) | (rn << 5) | rd; } public static int imm_shift(int opcode, int imm, int imms, int rn, int rd) { - return (opcode << 23) | (1 << 22) | (imm << 16) | (imms << 10) | (rn << 5) | rd; + return (opcode << 22) | (1 << 22) | (imm << 16) | (imms << 10) | (rn << 5) | rd; } public static void imm_inst(Encoding enc, Node n, int opcode, int imm12) { @@ -224,6 +225,20 @@ public class arm extends Machine { enc.add4(body); } + public static void imm_inst_n(Encoding enc, Node n, int opcode, int imm13) { + short self = enc.reg(n); + short reg1 = enc.reg(n.in(1)); + + int body = imm_inst_n(opcode, imm13, reg1, self); + enc.add4(body); + } + + // nth bit comes from immediate and not opcode + public static int imm_inst_n(int opcode, int imm13, int rn, int rd) { + assert 0 <= imm13 && imm13 <= 0x1FFF; + return (opcode << 23) | (imm13 << 10) | (rn << 5) | rd; + } + public static int imm_inst_l(Encoding enc, Node n, int opcode, int imm12) { short self = enc.reg(n); short reg1 = enc.reg(n.in(1)); @@ -272,6 +287,10 @@ public class arm extends Machine { return (opcode << 23) | (shift << 21) | (imm16 << 5) | rd; } + public static int mov_reg(int opcode, int src, int dst) { + return (opcode << 21) | (src << 16) | 0b11111 << 5 | dst; + } + public static int ret(int opcode) { return (opcode << 10); } @@ -284,6 +303,13 @@ public class arm extends Machine { public static int f_scalar(int opcode, int ftype, int rm, int op, int rn, int rd) { return (opcode << 24) | (ftype << 22) | (1 << 21) | (rm << 16) | (op << 10) | (rn << 5) | rd; } + + public static int f_mov_reg(int opcode, int rn, int rd) { + return (opcode << 24) | (0b01100000010000 << 10) | (rn << 5) | rd; + } + public static int f_mov_general(int opcode, int ftype, int rmode, int opcode1, int rn, int rd) { + return (opcode << 24) |(ftype << 22) | (1 << 21) | (rmode << 19) | (opcode1 << 16) | (rn << 5) | rd; + } public static void f_scalar(Encoding enc, Node n, int op ) { short self = (short)(enc.reg(n) -D_OFFSET); short reg1 = (short)(enc.reg(n.in(1))-D_OFFSET); @@ -310,8 +336,8 @@ public class arm extends Machine { return (opcode << 21) | (off << 16) | (option.ordinal() << 13) | (s << 12) | (2 << 10) | (ptr << 5) | rt; } // [Rptr+imm9] - public static int load_str_imm(int opcode, int imm9, int ptr, int rt) { - return (opcode << 21) | (imm9 << 12) |(1 << 10) |(ptr << 5) | rt; + public static int load_str_imm(int opcode, int imm12, int ptr, int rt) { + return (opcode << 22) | (imm12 << 10) |(ptr << 5) | rt; } // encoding for vcvt, size is encoded in operand diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AddFRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AddFRISC.java index a1c23861..4d2ac916 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AddFRISC.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AddFRISC.java @@ -4,13 +4,13 @@ import com.seaofnodes.simple.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; -// fadd.s +// fadd.d public class AddFRISC extends MachConcreteNode implements MachNode { AddFRISC(Node addf) {super(addf);} @Override public String op() { return "addf"; } @Override public RegMask regmap(int i) { assert i==1 || i==2; return riscv.FMASK; } @Override public RegMask outregmap() { return riscv.FMASK; } - @Override public void encoding( Encoding enc ) { riscv.rf_type(enc,this,0x53,riscv.RM.RNE,0); } + @Override public void encoding( Encoding enc ) { riscv.rf_type(enc,this,riscv.RM.RNE,1); } @Override public void asm(CodeGen code, SB sb) { sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" + ").p(code.reg(in(2))); } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/DivFRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/DivFRISC.java index fa3c0249..c67d7b3d 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/DivFRISC.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/DivFRISC.java @@ -4,13 +4,13 @@ import com.seaofnodes.simple.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; -// fdiv.s +// fdiv.d public class DivFRISC extends MachConcreteNode implements MachNode{ DivFRISC(Node divf) {super(divf);} @Override public String op() { return "divf"; } @Override public RegMask regmap(int i) { assert i==1 || i==2; return riscv.FMASK; } @Override public RegMask outregmap() { return riscv.FMASK; } - @Override public void encoding( Encoding enc ) { riscv.rf_type(enc,this,0x53,riscv.RM.RUP,0xC); } + @Override public void encoding( Encoding enc ) { riscv.rf_type(enc,this,riscv.RM.RUP,13); } // Default on double precision for now(64 bits) // General form: "fdiv.d rd = src1 / src2 @Override public void asm(CodeGen code, SB sb) { diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/I2F8RISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/I2F8RISC.java index 12ffe364..a6f84c19 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/I2F8RISC.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/I2F8RISC.java @@ -14,7 +14,7 @@ public class I2F8RISC extends MachConcreteNode implements MachNode { @Override public void encoding( Encoding enc ) { short dst = (short)(enc.reg(this )-riscv.F_OFFSET); short src1 = enc.reg(in(1)); - int body = riscv.r_type(riscv.OP_FP,dst,riscv.RM.RNE.ordinal(),src1,0,0x68); + int body = riscv.r_type(0b1010011,dst,riscv.RM.RNE.ordinal(),src1,0,0x69); enc.add4(body); } @Override public void asm(CodeGen code, SB sb) { diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/LoadRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/LoadRISC.java index 6d7535e2..a3309038 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/LoadRISC.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/LoadRISC.java @@ -17,7 +17,7 @@ public class LoadRISC extends MemOpRISC { @Override public void encoding( Encoding enc ) { short dst = xreg(enc); short ptr = enc.reg(ptr()); - int body = riscv.i_type(opcode(enc), dst, func3(), ptr, _off); + int body = riscv.i_type(opcode(enc), dst, func3(), ptr, _off); enc.add4(body); } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MemOpRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MemOpRISC.java index acb7fbc1..1e19dfd4 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MemOpRISC.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MemOpRISC.java @@ -38,13 +38,29 @@ public abstract class MemOpRISC extends MemOpNode implements MachNode { if( _declaredType == TypeInteger.BOOL) func3=4; // LBU if( _declaredType == TypeInteger.U16 ) func3=5; // LHU if( _declaredType == TypeInteger.U32 ) func3=6; // LWU + // float + if(_declaredType == TypeFloat.F32) func3 = 2; // fLW fSW + if(_declaredType == TypeFloat.F64) func3 = 3; // fLD fSD if( _declaredType instanceof TypeMemPtr ) func3=6; // 4 byte pointers, assumed unsigned? if( func3 == -1 ) throw Utils.TODO(); return func3; } // 7 bits, 00 000 11 or 00 001 11 for FP - int opcode(Encoding enc) { return enc.reg(this ) < riscv.F_OFFSET ? 3 : 7; } + int opcode(Encoding enc) { + if(enc.reg(this) < riscv.F_OFFSET) return 3; + else { + if(this instanceof LoadRISC) { + // opcode is same for 32 bit and 64 bits + return 7; + } + if(this instanceof StoreRISC) { + // opcode is the same for 32 bit and 64 bits + return 39; + } + } + return enc.reg(this ) < riscv.F_OFFSET ? 3 : 7; + } short xreg(Encoding enc) { short xreg = enc.reg(this ); return xreg < riscv.F_OFFSET ? xreg : (short)(xreg-riscv.F_OFFSET); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MulFRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MulFRISC.java index 1612854d..c9917b4f 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MulFRISC.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MulFRISC.java @@ -4,13 +4,13 @@ import com.seaofnodes.simple.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; -// fmul.s +// fmul.d public class MulFRISC extends MachConcreteNode implements MachNode { MulFRISC(Node mulf) {super(mulf);} @Override public String op() { return "mulf"; } @Override public RegMask regmap(int i) { assert i==1 || i==2; return riscv.FMASK; } @Override public RegMask outregmap() { return riscv.FMASK; } - @Override public void encoding( Encoding enc ) { riscv.rf_type(enc,this,0x53,riscv.RM.RNE,0x9); } + @Override public void encoding( Encoding enc ) { riscv.rf_type(enc,this,riscv.RM.RNE,9); } @Override public void asm(CodeGen code, SB sb) { sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" * ").p(code.reg(in(2))); } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NewRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NewRISC.java index 7d43e1ec..7dbdf9bb 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NewRISC.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/NewRISC.java @@ -21,8 +21,9 @@ public class NewRISC extends NewNode implements MachNode { // Generic external encoding; 2 ops. enc.external(this,"calloc"); // A1 is a caller-save, allowed to crush building external address + // auipc enc.add4(riscv.u_type(0x17, riscv.A1, 0)); - enc.add4(riscv.i_type(0x67, riscv.RPC, riscv.I_JALR, riscv.A1, 0)); + enc.add4(riscv.i_type(0x67, riscv.RPC, 0, riscv.A1, 0)); } // General form: "alloc #bytes PC" diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SplitRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SplitRISC.java index c6a31bdb..a322e8e4 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SplitRISC.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SplitRISC.java @@ -19,15 +19,18 @@ public class SplitRISC extends SplitNode { if( dst >= riscv.MAX_REG ) { // Store to SP - if( src >= riscv.MAX_REG ) + if( src >= riscv.MAX_REG ) { throw Utils.TODO(); // Very rare stack-stack move + } + int off = enc._fun.computeStackSlot(dst - riscv.MAX_REG)*8; - throw Utils.TODO(); + // store 64 bit values + enc.add4(riscv.s_type(39, 3, riscv.SP, dst, off)); } if( src >= riscv.MAX_REG ) { // Load from SP int off = enc._fun.computeStackSlot(src - riscv.MAX_REG)*8; - throw Utils.TODO(); + enc.add4(riscv.i_type(7, dst, 3,riscv.SP, off)); } // pick opcode based on regs if( !dstX && !srcX ) { @@ -35,13 +38,17 @@ public class SplitRISC extends SplitNode { enc.add4(riscv.r_type(riscv.OP,dst,0,src,riscv.ZERO,0)); } else if( dstX && srcX ) { // FPR->FPR - throw Utils.TODO(); + // Can do: FPR->GPR->FPR + enc.add4(riscv.r_type(0b1010011, dst, 0, src, 0, 0b1110001)); + enc.add4(riscv.r_type(0b1010011, dst, 0, src, 0, 0b0100000)); } else if( dstX && !srcX ) { //GPR->FPR - throw Utils.TODO(); + // fmv.d.x + enc.add4(riscv.r_type(0b1010011, dst, 0, src, 0, 0b0100000)); } else if( !dstX && srcX ) { //FPR->GPR - throw Utils.TODO(); + //fmv.x.d + enc.add4(riscv.r_type(0b1010011, dst, 0, src, 0, 0b1110001)); } } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/StoreRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/StoreRISC.java index 11ff42a7..b97117d5 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/StoreRISC.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/StoreRISC.java @@ -34,7 +34,7 @@ public class StoreRISC extends MemOpRISC { @Override public void encoding( Encoding enc ) { short val = xreg(enc); short ptr = enc.reg(ptr()); - int body = riscv.s_type(opcode(enc), ptr, func3()&3, val, _off); + int body = riscv.s_type(opcode(enc), func3()&3, ptr, val, _off); enc.add4(body); } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SubFRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SubFRISC.java index c59a70b4..1e1b43c7 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SubFRISC.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SubFRISC.java @@ -4,13 +4,13 @@ import com.seaofnodes.simple.SB; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; -// fsub.s +// fsub.d public class SubFRISC extends MachConcreteNode implements MachNode { SubFRISC(Node subf) {super(subf);} @Override public String op() { return "subf"; } @Override public RegMask regmap(int i) { assert i==1 || i==2; return riscv.FMASK; } @Override public RegMask outregmap() { return riscv.FMASK; } - @Override public void encoding( Encoding enc ) { riscv.rf_type(enc,this,0x53,riscv.RM.RNE,0x5); } + @Override public void encoding( Encoding enc ) { riscv.rf_type(enc,this,riscv.RM.RNE,5); } @Override public void asm(CodeGen code, SB sb) { sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" + ").p(code.reg(in(2))); } 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 4e223f73..9bf560cf 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 @@ -106,13 +106,12 @@ public class riscv extends Machine { // // major opcode: OP public static int OP = 0b01_100_11; - public static int OP_FP = 0b11_100_11; + public static int OP_FP = 0b10_100_11; //I_type opcode: 0010 0011 public static int I_TYPE = 0x13; // 0110 0111 - public static int I_JALR = 0x67; public static int J_JAL = 0b1101111; @@ -127,7 +126,7 @@ public class riscv extends Machine { int body = r_type(OP,dst,func3,src1,src2,func7); enc.add4(body); } - public static void rf_type(Encoding enc, Node n, int opcode, RM func3, int func7) { + public static void rf_type(Encoding enc, Node n, RM func3, int func7) { short dst = (short)(enc.reg(n )-F_OFFSET); short src1 = (short)(enc.reg(n.in(1))-F_OFFSET); short src2 = (short)(enc.reg(n.in(2))-F_OFFSET); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFX86.java index 720be638..a4166bc7 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFX86.java @@ -12,7 +12,6 @@ public class AddFX86 extends MachConcreteNode implements MachNode { @Override public int twoAddress() { return 1; } @Override public boolean commutes() { return true; } - // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { // F2 0F 58 /r ADDSD xmm1, xmm2/m64 short dst = (short)(enc.reg(this ) - x86_64_v2.XMM_OFFSET); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallX86.java index fc1da246..f4e243bc 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallX86.java @@ -24,7 +24,6 @@ public class CallX86 extends CallNode implements MachNode, RIPRelSize { @Override public RegMask outregmap() { return null; } @Override public int nargs() { return nIns()-2; } // Minus control, memory, fptr - // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { enc.relo(this).add1(0xe8).add4(0); } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpFX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpFX86.java index c2d0ff0f..35b92170 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpFX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpFX86.java @@ -10,7 +10,6 @@ public class CmpFX86 extends MachConcreteNode implements MachNode { @Override public RegMask regmap(int i) { return x86_64_v2.XMASK; } @Override public RegMask outregmap() { return x86_64_v2.FLAGS_MASK; } - // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { // UCOMISD short src1 = (short)(enc.reg(in(1)) - x86_64_v2.XMM_OFFSET); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpIX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpIX86.java index ccb79710..6271afcd 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpIX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpIX86.java @@ -29,7 +29,7 @@ public class CmpIX86 extends MachConcreteNode implements MachNode { @Override public RegMask outregmap() { return x86_64_v2.FLAGS_MASK; } @Override public boolean isClone() { return true; } @Override public Node copy() { return new CmpIX86(this); } - // Encoding is appended into the byte array; size is returned + @Override public final void encoding( Encoding enc ) { short dst = enc.reg(this); // Also src1 enc.add1(x86_64_v2.rex(0, dst, 0)); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivFX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivFX86.java index cc89e808..9509a1f5 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivFX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivFX86.java @@ -11,7 +11,6 @@ public class DivFX86 extends MachConcreteNode implements MachNode { @Override public RegMask outregmap() { return x86_64_v2.XMASK; } @Override public int twoAddress() { return 1; } - // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { // F2 0F 5E /r DIVSD xmm1, xmm2/m64 short dst = (short)(enc.reg(this ) - x86_64_v2.XMM_OFFSET); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FltX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FltX86.java index 307d745f..708269bd 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FltX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FltX86.java @@ -13,7 +13,6 @@ public class FltX86 extends ConstantNode implements MachNode, RIPRelSize { @Override public boolean isClone() { return true; } @Override public Node copy() { return new FltX86(this); } - // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { // Load the constant into a FPR // movsd xmm, [rip + 0] diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/I2f8X86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/I2f8X86.java index ef821e83..d3213ae4 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/I2f8X86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/I2f8X86.java @@ -10,7 +10,6 @@ public class I2f8X86 extends MachConcreteNode implements MachNode { @Override public RegMask regmap(int i) { assert i==1; return x86_64_v2.WMASK; } @Override public RegMask outregmap() { return x86_64_v2.XMASK; } - // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { // F2 0F 2A /r CVTSI2SD xmm1, r32/m32 short dst = (short)(enc.reg(this ) - x86_64_v2.XMM_OFFSET); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ImmX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ImmX86.java index e3285d55..760d6805 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ImmX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ImmX86.java @@ -19,7 +19,6 @@ public abstract class ImmX86 extends MachConcreteNode implements MachNode { abstract int opcode(); abstract int mod(); - // Encoding is appended into the byte array; size is returned @Override public final void encoding( Encoding enc ) { short dst = enc.reg(this); // Also src1 enc.add1(x86_64_v2.rex(0, dst, 0)); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/JmpX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/JmpX86.java index 876660aa..10b111e4 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/JmpX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/JmpX86.java @@ -27,7 +27,6 @@ public class JmpX86 extends IfNode implements MachNode, RIPRelSize { @Override public RegMask outregmap() { return null; } @Override public void invert() { _bop = invert(_bop); } - // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { enc.jump(this,cproj(0)); int op = x86_64_v2.jumpop(_bop); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LeaX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LeaX86.java index cdae9f93..dce8a49a 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LeaX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LeaX86.java @@ -22,7 +22,6 @@ public class LeaX86 extends MachConcreteNode implements MachNode { @Override public RegMask regmap(int i) { assert i==1 || i==2; return x86_64_v2.RMASK; } @Override public RegMask outregmap() { return x86_64_v2.WMASK; } - // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { // REX.W + 8D /r LEA r64,m short dst = enc.reg(this); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LoadX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LoadX86.java index 6dd3e3dc..16f36173 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LoadX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/LoadX86.java @@ -5,6 +5,7 @@ import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.LoadNode; import com.seaofnodes.simple.node.Node; import com.seaofnodes.simple.type.Type; +import com.seaofnodes.simple.type.TypeFloat; import com.seaofnodes.simple.type.TypeInteger; public class LoadX86 extends MemOpX86 { @@ -21,10 +22,25 @@ public class LoadX86 extends MemOpX86 { short dst = enc.reg(this ); short ptr = enc.reg(ptr()); short idx = enc.reg(idx()); - if (_declaredType != TypeInteger.U32) { + + if (_declaredType != TypeInteger.U32 && _declaredType != TypeFloat.F32 && _declaredType != TypeFloat.F64) { enc.add1(x86_64_v2.rex(dst, ptr, idx)); } + if(_declaredType == TypeFloat.F32) { + // F3 0F 10 /r MOVSS xmm1, m32 + enc.add1(0xF3); + enc.add1(0x0F); + enc.add1(0x10); + dst -= (short)x86_64_v2.XMM_OFFSET; + } + if(_declaredType == TypeFloat.F64) { + // F2 0F 10 /r MOVSD xmm1, m64 + enc.add1(0xF2); + enc.add1(0x0F); + enc.add1(0x10); + dst -= (short)x86_64_v2.XMM_OFFSET; + } if(_declaredType == TypeInteger.I8) { // sign extend: REX.W + 0F BE /r MOVSX r64, r/m8 enc.add1(0x0F); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulFX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulFX86.java index 0af87037..c1edb082 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulFX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulFX86.java @@ -12,7 +12,6 @@ public class MulFX86 extends MachConcreteNode implements MachNode { @Override public int twoAddress() { return 1; } @Override public boolean commutes() { return true; } - // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { // F2 0F 59 /r MULSD xmm1,xmm2/m64 short dst = (short)(enc.reg(this ) - x86_64_v2.XMM_OFFSET); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulX86.java index 8800f159..3cd1f795 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulX86.java @@ -12,7 +12,6 @@ public class MulX86 extends MachConcreteNode implements MachNode { @Override public int twoAddress() { return 1; } @Override public boolean commutes() { return true; } - // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { // REX.W + 0F AF /r IMUL r64, r/m64 short dst = enc.reg(this ); // src1 diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NewX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NewX86.java index 6263213d..456d0093 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NewX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NewX86.java @@ -15,7 +15,6 @@ public class NewX86 extends NewNode implements MachNode { @Override public RegMask outregmap() { return null; } @Override public RegMask killmap() { return x86_64_v2.x86CallerSave(); } - // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { enc.external(this,"calloc"); // E8 cd CALL rel32; diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SetX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SetX86.java index 1d8fa127..36e32bb8 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SetX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SetX86.java @@ -20,7 +20,6 @@ public class SetX86 extends MachConcreteNode implements MachNode { @Override public RegMask regmap(int i) { assert i==1; return x86_64_v2.FLAGS_MASK; } @Override public RegMask outregmap() { return x86_64_v2.WMASK; } - // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { // REX + 0F 94 short dst = enc.reg(this ); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SplitX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SplitX86.java index 15657de0..a718ee51 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SplitX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SplitX86.java @@ -14,7 +14,6 @@ public class SplitX86 extends SplitNode { // Need to handle 8 cases: . reg->reg, reg->xmm, reg->flags, xmm->reg, xmm->xmm, xmm->flags, flags->reg, flags->xmm, // flags->flags. - // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { // REX.W + 8B /r MOV r64, r/m64 short dst = enc.reg(this ); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java index 8c2e0612..9a5d7925 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java @@ -5,6 +5,8 @@ import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.ConstantNode; import com.seaofnodes.simple.node.Node; import com.seaofnodes.simple.node.StoreNode; +import com.seaofnodes.simple.type.TypeFloat; + import java.util.BitSet; public class StoreX86 extends MemOpX86 { @@ -33,11 +35,12 @@ public class StoreX86 extends MemOpX86 { if(imm_op == -1) {enc.add1(x86_64_v2.rex(src, ptr, idx));enc.add1(0xC7); } else enc.add1(imm_op); } else { - - if(_declaredType.log_size() == 0) enc.add1(0x88); - if(_declaredType.log_size() == 1) enc.add1(0x89); - if(_declaredType.log_size() == 2) enc.add1(0x89); - if(_declaredType.log_size() == 3) {enc.add1(x86_64_v2.rex(src, ptr, idx)); enc.add1(0x89);} + if(_declaredType == TypeFloat.F32) {src -= (short)x86_64_v2.XMM_OFFSET; enc.add1(0xF3); enc.add1(0x0F); enc.add1(0x11);} + else if(_declaredType == TypeFloat.F64) {src -= (short)x86_64_v2.XMM_OFFSET; enc.add1(0xF2); enc.add1(0x0F); enc.add1(0x11);} + else if(_declaredType.log_size() == 0) enc.add1(0x88); + else if(_declaredType.log_size() == 1) enc.add1(0x89); + else if(_declaredType.log_size() == 2) enc.add1(0x89); + else if(_declaredType.log_size() == 3) {enc.add1(x86_64_v2.rex(src, ptr, idx)); enc.add1(0x89);} } x86_64_v2.indirectAdr(_scale, idx, ptr, _off, src, enc); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SubFX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SubFX86.java index 07084932..0a169a22 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SubFX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SubFX86.java @@ -11,7 +11,6 @@ public class SubFX86 extends MachConcreteNode implements MachNode { @Override public RegMask outregmap() { return x86_64_v2.XMASK; } @Override public int twoAddress() { return 1; } - // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { // F2 0F 5C /r SUBSD xmm1, xmm2/m64 short dst = (short)(enc.reg(this ) - x86_64_v2.XMM_OFFSET); diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java index 01b878a0..f51e0c75 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java @@ -434,8 +434,9 @@ public class x86_64_v2 extends Machine { if( lhs instanceof LoadNode ld && ld.nOuts() == 1 && ld._declaredType.log_size() >= 3) return new AddMemX86(add, address(ld), ld.ptr(), idx, off, scale, imm(rhs), val); - if(rhs instanceof LoadNode ld && ld.nOuts() == 1 && ld._declaredType.log_size() >= 3) - throw Utils.TODO(); // Swap load sides +// if(rhs instanceof LoadNode ld && ld.nOuts() == 1 && ld._declaredType.log_size() >= 3) { +// throw Utils.TODO(); // Swap load sides +// } // Attempt a full LEA-style break down. // Returns one of AddX86, AddIX86, LeaX86, or LHS @@ -463,8 +464,8 @@ public class x86_64_v2 extends Machine { if(addf.in(1) instanceof LoadNode ld && ld.nOuts() == 1) return new AddFMemX86(addf, address(ld), ld.ptr(), idx, off, scale, addf.in(2)); - if(addf.in(2) instanceof LoadNode ld && ld.nOuts() == 1) - throw Utils.TODO(); // Swap load sides +// if(addf.in(2) instanceof LoadNode ld && ld.nOuts() == 1) +// throw Utils.TODO(); // Swap load sides return new AddFX86(addf); } |
