package tools;
import java.util.*;
public abstract class Operand
{
String type;
public Operand(String type)
{
this.type = type;
}
public String toString()
{
return type;
}
public abstract int getSize();
public abstract String define(int arg);
public abstract String construct(int arg);
public abstract String directConstruct(int arg);
public abstract String load(int arg);
public abstract String set(int arg);
public abstract String get(int arg);
public String get16(int arg)
{
throw new IllegalStateException("Unimplemented get16!");
}
public String get32(int arg)
{
throw new IllegalStateException("Unimplemented get32!");
}
public String set16(int arg)
{
throw new IllegalStateException("Unimplemented set16!");
}
public String set32(int arg)
{
throw new IllegalStateException("Unimplemented set32!");
}
public boolean needsModrm()
{
return false;
}
public String setF(int arg)
{
throw new IllegalStateException("Unimplemented setF!");
}
public String getF(int arg)
{
throw new IllegalStateException("Unimplemented getF!");
}
public String setA(int arg)
{
throw new IllegalStateException("Unimplemented setA!");
}
public String getA(int arg)
{
throw new IllegalStateException("Unimplemented getA!");
}
public static class Reg extends Operand
{
final int size;
public Reg(String name, int size)
{
super(name);
this.size = size;
}
public int getSize()
{
return size;
}
public String define(int arg)
{
return " final int "+getVal(arg)+";\n";
}
public String construct(int arg)
{
return " "+getVal(arg) + " = Processor.getRegIndex(parent.operand["+(arg-1)+"].toString());";
}
public String directConstruct(int arg)
{
return " "+getVal(arg) + " = Modrm."+type+"(modrm);";
}
public String load(int arg)
{
return " Reg op"+arg+" = cpu.regs["+getVal(arg)+"];";
}
public String set(int arg)
{
return "op"+arg+".set"+getSize()+"(";
}
public String get(int arg)
{
return "op"+arg+".get"+getSize()+"()";
}
private String getVal(int arg)
{
return "op"+arg+"Index";
}
public String get16(int arg)
{
return "op"+arg+".get16(";
}
public String get32(int arg)
{
return "op"+arg+".get32(";
}
public String set16(int arg)
{
return "op"+arg+".set16(";
}
public String set32(int arg)
{
return "op"+arg+".set32(";
}
}
public static class ControlReg extends Operand
{
public ControlReg(String name)
{
super(name);
}
public String define(int arg)
{
return " final int "+getVal(arg)+";\n";
}
public String construct(int arg)
{
return " "+getVal(arg) + " = Processor.getCRIndex(parent.operand["+(arg-1)+"].toString());";
}
public String directConstruct(int arg)
{
return " "+getVal(arg) + " = Modrm.reg(modrm);";
}
public String load(int arg)
{
return "";
}
public String set(int arg)
{
return "cpu.setCR("+getVal(arg)+", ";
}
public String get(int arg)
{
return "cpu.getCR("+getVal(arg)+")";
}
private String getVal(int arg)
{
return "op"+arg+"Index";
}
public int getSize()
{
return 32;
}
}
public static class DebugReg extends Operand
{
public DebugReg(String name)
{
super(name);
}
public String define(int arg)
{
return " final int "+getVal(arg)+";\n";
}
public String construct(int arg)
{
return " "+getVal(arg) + " = Processor.getDRIndex(parent.operand["+(arg-1)+"].toString());";
}
public String directConstruct(int arg)
{
return " "+getVal(arg) + " = Modrm.reg(modrm);";
}
public String load(int arg)
{
return "";
}
public String set(int arg)
{
return "cpu.setDR("+getVal(arg)+", ";
}
public String get(int arg)
{
return "cpu.getDR("+getVal(arg)+")";
}
private String getVal(int arg)
{
return "op"+arg+"Index";
}
public int getSize()
{
return 32;
}
}
public static class STi extends Operand
{
final int num;
public STi(String name)
{
super(name);
this.num = Integer.parseInt(name.substring(2));
}
public String define(int arg)
{
return "";
}
public String construct(int arg)
{
return "";
}
public String directConstruct(int arg)
{
return "";
}
public String load(int arg)
{
return "";
}
public String set(int arg)
{
return "cpu.fpu.setST("+num+", ";
}
public String get(int arg)
{
return "cpu.fpu.ST("+num+")";
}
public int getSize()
{
return 64;
}
}
public static class SpecificReg extends Operand
{
final int size;
final String name;
public SpecificReg(String type, String name, int size)
{
super(type);
this.size = size;
this.name = name;
}
public int getSize()
{
return size;
}
public String define(int arg)
{
return "";
}
public String directConstruct(int arg)
{
return "";
}
public String construct(int arg)
{
return "";
}
public String load(int arg)
{
return "";
}
public String set(int arg)
{
return name+".set"+getSize()+"(";
}
public String get(int arg)
{
return name+".get"+getSize()+"()";
}
}
public static class Mem extends Operand
{
final int size;
public Mem(String name, int size)
{
super(name);
this.size = size;
}
public boolean needsModrm()
{
if (type.startsWith("E"))
return true;
if (type.startsWith("M"))
return true;
if (type.startsWith("O"))
return false;
throw new IllegalStateException("Does Mem type "+ type + " need modrm?");
}
public int getSize()
{
return size;
}
public String define(int arg)
{
return " final Pointer op"+arg+";\n";
}
public String construct(int arg)
{
return " op"+arg+" = new Pointer(parent.operand["+(arg-1)+"], parent.adr_mode);";
}
public String directConstruct(int arg)
{
if (needsModrm())
return " op"+arg+" = Modrm.getPointer(prefices, modrm, input);";
else
return " op"+arg+" = Modrm."+type+"(prefices, input);";
}
public String load(int arg)
{
return "";
}
public String set(int arg)
{
return "op"+arg+".set"+getSize()+"(cpu, ";
}
public String get(int arg)
{
return "op"+arg+".get"+getSize()+"(cpu)";
}
public String setF(int arg)
{
return "op"+arg+".setF"+getSize()+"(cpu, ";
}
public String getF(int arg)
{
return "op"+arg+".getF"+getSize()+"(cpu)";
}
public String setA(int arg)
{
return "op"+arg+".set"+getSize()+"(cpu, ";
}
public String getA(int arg)
{
return "op"+arg+".get"+getSize()+"(cpu, ";
}
public String get16(int arg)
{
return "op"+arg+".get16(cpu, ";
}
public String get32(int arg)
{
return "op"+arg+".get32(cpu, ";
}
public String set16(int arg)
{
return "op"+arg+".set16(cpu, ";
}
public String set32(int arg)
{
return "op"+arg+".set32(cpu, ";
}
}
public static class Segment extends Operand
{
final int size=16;
public Segment(String name)
{
super(name);
}
public int getSize()
{
return size;
}
public String define(int arg)
{
return " public final int segIndex;\n";
}
public String construct(int arg)
{
return " segIndex = Processor.getSegmentIndex(parent.operand["+(arg-1)+"].toString());";
}
public String directConstruct(int arg)
{
return " segIndex = Modrm.reg(modrm);";
}
public String load(int arg)
{
if (arg != 1)
return " Segment seg = cpu.segs[segIndex];";
else
return "";
}
public String set(int arg)
{
return "cpu.setSeg(segIndex, ";
}
public String get(int arg)
{
return "seg.getSelector()";
}
}
public static class SpecificSegment extends Operand
{
final int size=16;
final String name;
public SpecificSegment(String type, String name)
{
super(type);
this.name = name;
}
public int getSize()
{
return size;
}
public String define(int arg)
{
return "";
}
public String construct(int arg)
{
return "";
}
public String directConstruct(int arg)
{
return "";
}
public String load(int arg)
{
return "";
}
public String set(int arg)
{
return "cpu."+name+"(";
}
public String get(int arg)
{
return "cpu."+name+"()";
}
}
public static class Address extends Operand
{
public Address(String name)
{
super(name);
}
public int getSize()
{
return 0;
}
public String define(int arg)
{
return " final Pointer op"+arg+";\n";
}
public String construct(int arg)
{
return " op"+arg+" = new Address();//won't work any more delete soon";
}
public String directConstruct(int arg)
{
return " op"+arg+" = Modrm.getPointer(prefices, modrm, input);";
}
public String load(int arg)
{
return "";
}
public String set(int arg)
{
return "";
}
public String get(int arg)
{
return "op"+arg+".get(cpu)";
}
public String get16(int arg)
{
return "op"+arg+".get16(cpu, ";
}
public String get32(int arg)
{
return "op"+arg+".get32(cpu, ";
}
public String set16(int arg)
{
return "op"+arg+".set16(cpu, ";
}
public String set32(int arg)
{
return "op"+arg+".set32(cpu, ";
}
}
public static class Immediate extends Operand
{
final int size;
final String var;
public Immediate(String name, int size)
{
super(name);
this.size = size;
var = "imm"+name.charAt(name.length()-1);
}
public int getSize()
{
return size;
}
public String define(int arg)
{
return " final int "+var+";\n";
}
public String construct(int arg)
{
return " "+var+" = ("+cast()+")parent.operand["+(arg-1)+"].lval;";
}
public String directConstruct(int arg)
{
return " "+var+" = Modrm."+type+"(input);";
}
private String cast()
{
if (size == 8)
return "byte";
if (size == 16)
return "short";
if (size == 32)
return "int";
throw new IllegalStateException("Unknown immediate size "+size);
}
public String load(int arg)
{
return "";
}
public String set(int arg)
{
return "";
}
public String get(int arg)
{
return var;
}
}
public static class Constant extends Operand
{
final int val;
public Constant(String name, int val)
{
super(name);
this.val = val;
}
public int getSize()
{
return 0;
}
public String define(int arg)
{
return "";
}
public String construct(int arg)
{
return "";
}
public String directConstruct(int arg)
{
return "";
}
public String load(int arg)
{
return "";
}
public String set(int arg)
{
return "";
}
public String get(int arg)
{
return ""+val;
}
}
public static class Jump extends Operand
{
final int size;
public Jump(String name, int size)
{
super(name);
this.size = size;
}
public int getSize()
{
return size;
}
public String define(int arg)
{
return " final int jmp;\n";
}
public String construct(int arg)
{
return " jmp = ("+cast()+")parent.operand["+(arg-1)+"].lval;";
}
public String directConstruct(int arg)
{
return " jmp = Modrm."+type+"(input);";
}
private String cast()
{
if (size == 8)
return "byte";
if (size == 16)
return "short";
if (size == 32)
return "int";
throw new IllegalStateException("Unknown immediate size "+size);
}
public String load(int arg)
{
return "";
}
public String set(int arg)
{
return "";
}
public String get(int arg)
{
return "imm";
}
}
public static class FarPointer extends Operand
{
public FarPointer(String name)
{
super(name);
}
public int getSize()
{
return 0;
}
public String define(int arg)
{
return " final int cs, targetEip;\n";
}
public String construct(int arg)
{
return " targetEip = parent.operand["+(arg-1)+"].ptr.off;\n cs = parent.operand["+(arg-1)+"].ptr.seg;";
}
public String directConstruct(int arg)
{
return " targetEip = Modrm.jmpOffset(prefices, input);\n cs = Modrm.jmpCs(input);";
}
public String load(int arg)
{
return "";
}
public String set(int arg)
{
return "op"+arg+".set"+getSize()+"(cpu, ";
}
public String get(int arg)
{
return "op"+arg+".get"+getSize()+"(cpu)";
}
}
public static class FarMemPointer extends Operand
{
final int size;
public FarMemPointer(String name, int size)
{
super(name);
this.size = size;
}
public int getSize()
{
return size;
}
public String define(int arg)
{
return " final Pointer offset;\n";
}
public String construct(int arg)
{
return " offset = new Pointer(parent.operand["+(arg-1)+"], parent.adr_mode);";
}
public String directConstruct(int arg)
{
return " offset = Modrm.getPointer(prefices, modrm, input);";
}
public String load(int arg)
{
return " int cs = offset.get16(cpu, "+(size/8)+");\n int targetEip = offset.get"+size+"(cpu);";
}
public String set(int arg)
{
return "";
}
public String get(int arg)
{
return "";
}
}
public static Map<String, String> segs = new HashMap();
public static Map<String, String> reg8 = new HashMap();
public static Map<String, String> reg16 = new HashMap();
public static Map<String, String> reg16only = new HashMap();
static {
segs.put("CS", "cs");
segs.put("DS", "ds");
segs.put("ES", "es");
segs.put("FS", "fs");
segs.put("GS", "gs");
segs.put("SS", "ss");
reg8.put("AL", "cpu.r_al");
reg8.put("CL", "cpu.r_cl");
reg8.put("ALr8b", "cpu.r_al");
reg8.put("AHr12b", "cpu.r_ah");
reg8.put("BLr11b", "cpu.r_bl");
reg8.put("BHr15b", "cpu.r_bh");
reg8.put("CLr9b", "cpu.r_cl");
reg8.put("CHr13b", "cpu.r_ch");
reg8.put("DLr10b", "cpu.r_dl");
reg8.put("DHr14b", "cpu.r_dh");
reg16only.put("DX", "cpu.r_dx");
reg16only.put("AX", "cpu.r_ax");
reg16.put("rAXr8", "cpu.r_eax");
reg16.put("rAX", "cpu.r_eax");
reg16.put("eAX", "cpu.r_eax");
reg16.put("eBX", "cpu.r_ebx");
reg16.put("eCX", "cpu.r_ecx");
reg16.put("eDX", "cpu.r_edx");
reg16.put("eSP", "cpu.r_esp");
reg16.put("eBP", "cpu.r_ebp");
reg16.put("eSI", "cpu.r_esi");
reg16.put("eDI", "cpu.r_edi");
reg16.put("rBXr11", "cpu.r_ebx");
reg16.put("rCXr9", "cpu.r_ecx");
reg16.put("rDXr10", "cpu.r_edx");
reg16.put("rSPr12", "cpu.r_esp");
reg16.put("rBPr13", "cpu.r_ebp");
reg16.put("rSIr14", "cpu.r_esi");
reg16.put("rDIr15", "cpu.r_edi");
}
public static Operand get(String name, int opSize, boolean isMem)
{
if (name.equals("Ib"))
return new Immediate(name, 8);
if (name.equals("Iw"))
return new Immediate(name, 16);
if (name.equals("Id"))
return new Immediate(name, 32);
if (name.equals("I1"))
return new Constant(name, 1);
if (name.equals("Eb"))
{
if (isMem)
return new Mem(name, 8);
else
return new Reg(name, 8);
}
if (name.equals("Ew"))
{
if (isMem)
return new Mem(name, 16);
else
return new Reg(name, 16);
}
if (name.equals("Ed"))
{
if (isMem)
return new Mem(name, 32);
else
return new Reg(name, 32);
}
if (name.equals("Ob"))
return new Mem(name, 8);
if (name.equals("Ow"))
return new Mem(name, 16);
if (name.equals("Od"))
return new Mem(name, 32);
if (name.equals("Ep"))
return new FarMemPointer(name, opSize);
if (name.equals("R"))
return new Reg(name, opSize);
if (name.equals("C"))
return new ControlReg(name);
if (name.equals("D"))
return new DebugReg(name);
if (name.equals("Gb"))
return new Reg(name, 8);
if (name.equals("Gw"))
return new Reg(name, 16);
if (name.equals("Gd"))
return new Reg(name, 32);
if (name.equals("Jb"))
return new Jump(name, 8);
if (name.equals("Jw"))
return new Jump(name, 16);
if (name.equals("Jd"))
return new Jump(name, 32);
if (name.equals("Ap"))
return new FarPointer(name);
if (name.equals("M"))
return new Address(name);
if (name.equals("Mw"))
return new Mem(name, 16);
if (name.equals("Md"))
return new Mem(name, 32);
if (name.equals("Mq"))
return new Mem(name, 64);
if (name.equals("Mt"))
return new Mem(name, 80);
if (name.equals("S"))
return new Segment(name);
if (name.startsWith("ST"))
return new STi(name);
if (segs.containsKey(name))
return new SpecificSegment(name, segs.get(name));
if (reg8.containsKey(name))
return new SpecificReg(name, reg8.get(name), 8);
if (reg16.containsKey(name))
return new SpecificReg(name, reg16.get(name), opSize);
if (reg16only.containsKey(name))
return new SpecificReg(name, reg16only.get(name), 16);
throw new IllegalStateException("Unknown operand "+name+".");
}
}