public static x86Instruction Create(x86OpCode opCode, params Ix86Operand[] operands) { var ret = new x86Instruction(); ret.OpCode = opCode; ret.Operands = operands; return(ret); }
x86Register Normalize(x86Instruction instr) { if (instr.Operands.Length == 2 && instr.Operands[0] is x86ImmediateOperand && instr.Operands[1] is x86ImmediateOperand) { /* * op imm1, imm2 * ==> * mov reg, imm1 * op reg, imm2 */ x86Register reg = GetFreeRegister(); instrs.Add(x86Instruction.Create(x86OpCode.MOV, new x86RegisterOperand(reg), instr.Operands[0])); instr.Operands[0] = new x86RegisterOperand(reg); instrs.Add(instr); return(reg); } if (instr.Operands.Length == 1 && instr.Operands[0] is x86ImmediateOperand) { /* * op imm * ==> * mov reg, imm * op reg */ x86Register reg = GetFreeRegister(); instrs.Add(x86Instruction.Create(x86OpCode.MOV, new x86RegisterOperand(reg), instr.Operands[0])); instr.Operands[0] = new x86RegisterOperand(reg); instrs.Add(instr); return(reg); } if (instr.OpCode == x86OpCode.SUB && instr.Operands[0] is x86ImmediateOperand && instr.Operands[1] is x86RegisterOperand) { /* * sub imm, reg * ==> * neg reg * add reg, imm */ x86Register reg = ((x86RegisterOperand)instr.Operands[1]).Register; instrs.Add(x86Instruction.Create(x86OpCode.NEG, new x86RegisterOperand(reg))); instr.OpCode = x86OpCode.ADD; instr.Operands[1] = instr.Operands[0]; instr.Operands[0] = new x86RegisterOperand(reg); instrs.Add(instr); return(reg); } if (instr.Operands.Length == 2 && instr.Operands[0] is x86ImmediateOperand && instr.Operands[1] is x86RegisterOperand) { /* * op imm, reg * ==> * op reg, imm */ x86Register reg = ((x86RegisterOperand)instr.Operands[1]).Register; instr.Operands[1] = instr.Operands[0]; instr.Operands[0] = new x86RegisterOperand(reg); instrs.Add(instr); return(reg); } Debug.Assert(instr.Operands.Length > 0); Debug.Assert(instr.Operands[0] is x86RegisterOperand); if (instr.Operands.Length == 2 && instr.Operands[1] is x86RegisterOperand) { ReleaseRegister(((x86RegisterOperand)instr.Operands[1]).Register); } instrs.Add(instr); return(((x86RegisterOperand)instr.Operands[0]).Register); }