use of suite.assembler.Amd64 in project suite by stupidsing.
the class Amd64Dump method dump.
private String dump(Operand op0) {
int pointerSize = 4;
OpReg[] regs;
String name;
if (pointerSize == 4)
regs = amd64.reg32;
else if (pointerSize == 8)
regs = amd64.reg64;
else
return Fail.t();
if (op0 instanceof OpImm) {
OpImm opImm = (OpImm) op0;
return dump(opImm.imm, opImm.size);
} else if (op0 instanceof OpMem) {
OpMem opMem = (OpMem) op0;
int baseReg = opMem.baseReg;
int indexReg = opMem.indexReg;
String s = //
"" + //
(0 <= baseReg ? " + " + dump(regs[baseReg]) : "") + //
(0 <= indexReg ? " + " + dump(regs[indexReg]) + " * " + (1 << opMem.scale) : "") + (0 < opMem.dispSize ? dumpDisp(opMem.disp, pointerSize) : "");
return "[" + s.substring(3) + "]";
} else if ((name = (amd64.registerByName.inverse().get(op0).name)) != null)
return name;
else
return op0.toString();
}
use of suite.assembler.Amd64 in project suite by stupidsing.
the class Amd64Parse method parse.
public Instruction parse(Node node) {
Tree tree = Tree.decompose(node, TermOp.TUPLE_);
Insn insn = Enum.valueOf(Insn.class, ((Atom) tree.getLeft()).name);
Node ops = tree.getRight();
List<Operand> operands = scan(ops, ".0, .1").map(this::parseOperand).toList();
return //
amd64.instruction(//
insn, //
0 < operands.size() ? operands.get(0) : amd64.none, //
1 < operands.size() ? operands.get(1) : amd64.none, 2 < operands.size() ? operands.get(2) : amd64.none);
}
use of suite.assembler.Amd64 in project suite by stupidsing.
the class Amd64Parse method parseOpMem.
private Operand parseOpMem(Node[] m, int size) {
OpMem opMem = amd64.new OpMem();
opMem.size = size;
opMem.indexReg = -1;
opMem.baseReg = -1;
opMem.dispSize = 0;
for (Node component : scan(m[0], ".0 + .1")) if ((m = Suite.pattern(".0 * .1").match(component)) != null)
if (opMem.indexReg < 0) {
opMem.indexReg = amd64.regByName.get(m[0]).reg;
opMem.scale = ((Int) m[1]).number;
} else
Fail.t("bad operand");
else if (component instanceof Int)
if (opMem.dispSize == 0) {
opMem.disp = ((Int) component).number;
opMem.dispSize = 4;
} else
Fail.t("bad operand");
else if (opMem.baseReg < 0)
opMem.baseReg = amd64.regByName.get(component).reg;
else
Fail.t("bad operand");
return opMem;
}
use of suite.assembler.Amd64 in project suite by stupidsing.
the class Amd64Parse method parseOperand.
public Operand parseOperand(Node node) {
Operand operand;
Node[] m;
if ((operand = amd64.registerByName.get(node)) != null)
return operand;
else if ((m = Suite.pattern("BYTE `.0`").match(node)) != null)
return parseOpMem(m, 1);
else if ((m = Suite.pattern("WORD `.0`").match(node)) != null)
return parseOpMem(m, 2);
else if ((m = Suite.pattern("DWORD `.0`").match(node)) != null)
return parseOpMem(m, 4);
else if ((m = Suite.pattern("`.0`").match(node)) != null)
return parseOpMem(m, 4);
else if (node instanceof Int) {
OpImm opImm = amd64.new OpImm();
opImm.imm = ((Int) node).number;
opImm.size = 4;
return opImm;
} else
return Fail.t("bad operand");
}
use of suite.assembler.Amd64 in project suite by stupidsing.
the class P4DecomposeOperand method decomposeOpMem.
public OpMem decomposeOpMem(int fd, Funp n0, int disp0, int size) {
class Decompose {
private Operator operator;
private List<Funp> nodes = new ArrayList<>();
private Decompose(Operator operator) {
this.operator = operator;
}
private void decompose(Funp n_) {
FunpTree tree;
if (n_ instanceof FunpTree && (tree = (FunpTree) n_).operator == operator) {
decompose(tree.left);
decompose(tree.right);
} else
nodes.add(n_);
}
}
Fun2<Operator, Funp, List<Funp>> decompose = (operator, n_) -> {
Decompose dec = new Decompose(operator);
dec.decompose(n_);
return dec.nodes;
};
class DecomposeMult {
private long scale = 1;
private OpReg reg;
private List<Funp> mults = new ArrayList<>();
private void decompose(Funp n0) {
FunpTree2 tree;
Funp r;
for (Funp n1 : decompose.apply(TermOp.MULT__, n0)) if (n1 instanceof FunpFramePointer && isUseEbp && reg == null)
reg = amd64.ebp;
else if (n1 instanceof FunpNumber)
scale *= ((FunpNumber) n1).i.get();
else if (//
n1 instanceof FunpTree2 && //
(tree = (FunpTree2) n1).operator == TreeUtil.SHL && (r = tree.right) instanceof FunpNumber) {
decompose(tree.left);
scale <<= ((FunpNumber) r).i.get();
} else
mults.add(n1);
}
}
class DecomposePlus {
private OpReg baseReg = null, indexReg = null;
private int scale = 1, disp = disp0;
private boolean ok = is124(size);
private DecomposePlus(Funp n0) {
for (Funp n1 : decompose.apply(TermOp.PLUS__, n0)) if (n1 instanceof FunpFramePointer && !isUseEbp) {
addReg(amd64.esp, 1);
disp -= fd;
} else {
DecomposeMult dec = new DecomposeMult();
dec.decompose(n1);
if (dec.mults.isEmpty()) {
OpReg reg_ = dec.reg;
long scale_ = dec.scale;
if (reg_ != null)
addReg(reg_, scale_);
else
disp += scale_;
} else
ok = false;
}
}
private void addReg(OpReg reg_, long scale_) {
if (scale_ == 1 && baseReg == null)
baseReg = reg_;
else if (is1248(scale_) && indexReg == null) {
indexReg = reg_;
scale = (int) scale_;
} else
ok = false;
}
private OpMem op() {
return ok ? amd64.mem(baseReg, indexReg, scale, disp, size) : null;
}
}
return new DecomposePlus(n0).op();
}
Aggregations