/// <summary> /// Determines whether the specified <see cref="X86Instruction.OperandDescriptor"/> matches this /// <see cref="Operand"/>. /// </summary> /// <param name="descriptor">The <see cref="X86Instruction.OperandDescriptor"/> to match.</param> /// <returns><see langword="true"/> when the specified descriptor matches this operand; /// otherwise, <see langword="false"/>.</returns> internal override bool IsMatch(X86Instruction.OperandDescriptor descriptor) { switch (descriptor.OperandType) { case X86Instruction.OperandType.Immediate: return this.Size == DataSize.None || this.Size <= descriptor.Size; default: return false; } }
/// <summary> /// Tests that the given instruction fails. /// </summary> /// <param name="instruction">The <see cref="X86Instruction"/> instance to test.</param> private void AssertXBitInstructionFails(X86Instruction instruction, DataSize mode) { #region Contract if (instruction == null) throw new ArgumentNullException("instruction"); #endregion Assert.Throws<AssemblerException>(() => Assemble(instruction, mode)); }
/// <summary> /// Tests the given instruction. /// </summary> /// <param name="instruction">The <see cref="X86Instruction"/> instance to test.</param> /// <param name="expected">The expected result.</param> public void Assert64BitInstruction(X86Instruction instruction, byte[] expected) { AssertXBitInstruction(instruction, expected, DataSize.Bit64); }
/// <summary> /// Tests that the given instruction does not assemble. /// </summary> /// <param name="instruction">The <see cref="X86Instruction"/> instance to test.</param> /// <param name="nasmInstruction">The NASM string representation of the same instruction.</param> /// <param name="mode">The mode (16-bit, 32-bit or 64-bit) to use.</param> public void AssertInstructionFail(X86Instruction instruction, string nasmInstruction, DataSize mode) { #region Contract if (instruction == null) throw new ArgumentNullException("instruction"); if (nasmInstruction == null) throw new ArgumentNullException("nasmInstruction"); if (!Enum.IsDefined(typeof(DataSize), mode)) throw new InvalidEnumArgumentException("mode", (int)mode, typeof(DataSize)); if (mode != DataSize.Bit16 && mode != DataSize.Bit32 && mode != DataSize.Bit64) throw new ArgumentException(null, "mode"); #endregion var result = AssembleInstruction(instruction, nasmInstruction, mode); byte[] expected = result.Item1; byte[] actual = result.Item2; Assert.IsNull(expected); Assert.IsNull(actual); }
/// <summary> /// Assembles the given instruction. /// </summary> /// <param name="instruction">The <see cref="X86Instruction"/> instance to test.</param> /// <param name="nasmInstruction">The NASM string representation of the same instruction.</param> /// <param name="mode">The mode (16-bit, 32-bit or 64-bit) to use.</param> /// <returns>A (expected, actual) tuple.</returns> private Tuple<byte[], byte[]> AssembleInstruction(X86Instruction instruction, string nasmInstruction, DataSize mode) { #region Contract if (!Enum.IsDefined(typeof(DataSize), mode)) throw new InvalidEnumArgumentException("mode", (int)mode, typeof(DataSize)); if (mode != DataSize.Bit16 && mode != DataSize.Bit32 && mode != DataSize.Bit64) throw new ArgumentException(null, "mode"); #endregion // Assemble the NASM instruction. byte[] expected = null; if (nasmInstruction != null) { StringBuilder sb = new StringBuilder(); switch (mode) { case DataSize.Bit16: sb.AppendLine("[BITS 16]"); break; case DataSize.Bit32: sb.AppendLine("[BITS 32]"); break; case DataSize.Bit64: sb.AppendLine("[BITS 64]"); break; default: throw new NotSupportedException(); } sb.AppendLine(nasmInstruction); string feedback; expected = RunAssembler(sb.ToString(), out feedback); if (feedback != null && feedback.Length > 0) { Console.WriteLine("Assembler feedback:"); Console.WriteLine(feedback); } } // Assemble the SharpAssembler instruction. byte[] actual = null; if (instruction != null) { BinObjectFileFormat format = new BinObjectFileFormat(); var arch = new X86Architecture(CpuType.AmdBulldozer, mode); BinObjectFile objectFile = (BinObjectFile)format.CreateObjectFile(arch, "test"); Section textSection = objectFile.Sections.AddNew(SectionType.Program); var text = textSection.Contents; text.Add(instruction); try { using (MemoryStream ms = new MemoryStream()) { using (BinaryWriter writer = new BinaryWriter(ms)) { objectFile.Format.CreateAssembler(objectFile).Assemble(writer); actual = ms.ToArray(); } } } catch (AssemblerException ex) { Console.WriteLine(ex); actual = null; } } return new Tuple<byte[], byte[]>(expected, actual); }
/// <summary> /// Adjusts this <see cref="Operand"/> based on the specified <see cref="X86Instruction.OperandDescriptor"/>. /// </summary> /// <param name="descriptor">The <see cref="X86Instruction.OperandDescriptor"/> used to adjust.</param> /// <remarks> /// Only <see cref="X86Instruction.OperandDescriptor"/> instances for which <see cref="IsMatch"/> returns /// <see langword="true"/> may be used as a parameter to this method. /// </remarks> internal abstract void Adjust(X86Instruction.OperandDescriptor descriptor);
public void enumerateStep() { // decode bool programIsValid; X86Instruction[] trailProgram = decodeProgram(instructionEnumeration, out programIsValid); if (programIsValid) { // run the target program and the trailProgram and compare results IList <X86ExecutionContext> executionContextsToCheck = new List <X86ExecutionContext>(); executionContextsToCheck.Add(new X86ExecutionContext(8, 8)); /* * executionContextsToCheck.Add(new ExecutionContext(8, 8)); * executionContextsToCheck[0].integerRegisters[0] = 3; * executionContextsToCheck[0].integerRegisters[1] = 5; * executionContextsToCheck[1].integerRegisters[0] = 4; * executionContextsToCheck[1].integerRegisters[1] = 5; */ executionContextsToCheck[0].vectorRegisters[0] = new float[4] { 1.0f, 0.1f, 0.9f, 3.76f }; bool equalResultForAllContext = true; foreach (var executionCtxI in executionContextsToCheck) { X86ExecutionContext execCtxTarget = executionCtxI.deepClone(); interpret(execCtxTarget, targetProgram); X86ExecutionContext execCtxTrail = executionCtxI.deepClone(); interpret(execCtxTrail, trailProgram); /*if( execCtxTarget.integerRegisters[0] != execCtxTrail.integerRegisters[0] || execCtxTarget.integerRegisters[1] != execCtxTrail.integerRegisters[1] ) { * equalResultForAllContext = false; * break; * }*/ if (execCtxTarget.vectorRegisters[0][0] != execCtxTrail.vectorRegisters[0][0] || execCtxTarget.vectorRegisters[0][1] != execCtxTrail.vectorRegisters[0][1] || execCtxTarget.vectorRegisters[0][2] != execCtxTrail.vectorRegisters[0][2] || execCtxTarget.vectorRegisters[0][3] != execCtxTrail.vectorRegisters[0][3] ) { equalResultForAllContext = false; break; } } if (equalResultForAllContext) { int here = 5; throw new Exception("FOUND"); } } // increment and carry increment if (false) { Console.WriteLine("enumBefore {0} {1} {2} {3} {4} {5} {6} {7} ", instructionEnumeration[0], instructionEnumeration[1], instructionEnumeration[2], instructionEnumeration[3], instructionEnumeration[4], instructionEnumeration[5], instructionEnumeration[6], instructionEnumeration[7]); } for (int instructionIdx = 0; instructionIdx < 3; instructionIdx++) { int enumerationIdx = instructionIdx * widthOfInstructionEncoding; int idxOfImmediate2Encoding = enumerationIdx + 0; int idxOfTypeEncoding = enumerationIdx + 1; int idxOfDestEncoding = enumerationIdx + 2; int idxOfAEncoding = enumerationIdx + 3; var typeOfInstruction = decodeInstructionType(instructionEnumeration[idxOfTypeEncoding]); if (X86Instruction.doesInstructionNeedImmediate2(typeOfInstruction)) { instructionEnumeration[idxOfImmediate2Encoding]++; // check if we don't need to carry if (instructionEnumeration[idxOfImmediate2Encoding] < maximalValue[idxOfImmediate2Encoding]) { break; } // we need to carry instructionEnumeration[idxOfImmediate2Encoding] = 0; instructionEnumeration[idxOfTypeEncoding]++; } else { instructionEnumeration[idxOfTypeEncoding]++; } // check if we don't need to carry for the type if (instructionEnumeration[idxOfTypeEncoding] < maximalValue[idxOfTypeEncoding]) { break; } // we need to carry instructionEnumeration[idxOfTypeEncoding] = 0; instructionEnumeration[idxOfDestEncoding]++; if (instructionEnumeration[idxOfDestEncoding] < maximalValue[idxOfDestEncoding]) { break; } // we need to carry instructionEnumeration[idxOfDestEncoding] = 0; instructionEnumeration[idxOfAEncoding]++; if (instructionEnumeration[idxOfAEncoding] < maximalValue[idxOfAEncoding]) { break; } // we need to carry instructionEnumeration[idxOfAEncoding] = 0; // if we are here we carry into the next instruction } if (false) { Console.WriteLine("enumAfter {0} {1} {2} {3} {4} {5} {6} {7} ", instructionEnumeration[0], instructionEnumeration[1], instructionEnumeration[2], instructionEnumeration[3], instructionEnumeration[4], instructionEnumeration[5], instructionEnumeration[6], instructionEnumeration[7]); } // check for wrap around bool allZero = true; for (int enumerationIdx = 0; enumerationIdx < instructionEnumeration.Length; enumerationIdx++) { if (instructionEnumeration[enumerationIdx] != 0) { allZero = false; break; } } if (allZero) // if this is true then we are finished with the enumeration of the program with the length { int here5605 = 5; throw new Exception("WRAP AROUND"); } }
public static void JumpInstruction(ProgramSource ps, X86Assembly assembly, X86Instruction x86Instruction) { if (x86Instruction.OperandCount != 1) { throw new WrongParameterException(x86Instruction); } if (x86Instruction.Dst.Type != OperandTypes.Label || x86Instruction.Dst as LabelArgument == null) { throw new WrongParameterException(x86Instruction); } var dst = x86Instruction.Dst as LabelArgument; string instructionName = x86Instruction.Name; string realLabel = dst.Label; if (!assembly.LabelExists(realLabel)) { throw new LabelMissingException(x86Instruction.Line, realLabel); } string label = assembly.InternalNameOf(realLabel); switch (instructionName) { case "jmp": ps.AddCodeLine("goto ", label); return; case "je": ps.AddJump("ZF == 1", label); return; case "jne": ps.AddJump("ZF == 0", label); return; case "jg": ps.AddJump("ZF == 0 && SF == OF", label); return; case "jge": ps.AddJump("SF == OF", label); return; case "jl": ps.AddJump("SF != OF", label); return; case "jle": ps.AddJump("ZF == 1 || SF != OF", label); return; case "jz": ps.AddJump("ZF == 1", label); return; case "jnz": ps.AddJump("ZF == 0", label); return; case "loop": ps.AddCodeLine("vm.Ecx.Value--"); ps.AddJump("vm.Ecx.Value != 0", label); return; } Debug.Assert(false, "Unknown jump instruction"); }
public static void Generate(ProgramSource ps, X86Assembly assembly, X86Instruction x86Instruction) { var translator = new CSharpTranslator(assembly); var addressTranslator = new CSharpTranslator(assembly, true); switch (x86Instruction.Name) { case "add": if (x86Instruction.OperandCount != 2) { throw new WrongParameterException(x86Instruction); } if (x86Instruction.Dst.Type != OperandTypes.Memory && x86Instruction.Dst.Type != OperandTypes.Register) { throw new WrongParameterException(x86Instruction); } if (x86Instruction.Src.Type == OperandTypes.Label) { throw new WrongParameterException(x86Instruction); } ps.AddCodeLine(x86Instruction.Dst.GetCode(translator) + " += " + x86Instruction.Src.GetCode(translator)); break; case "and": if (x86Instruction.OperandCount != 2) { throw new WrongParameterException(x86Instruction); } if (x86Instruction.Dst.Type != OperandTypes.Memory && x86Instruction.Dst.Type != OperandTypes.Register) { throw new WrongParameterException(x86Instruction); } if (x86Instruction.Src.Type == OperandTypes.Label) { throw new WrongParameterException(x86Instruction); } ps.AddCodeLine(x86Instruction.Dst.GetCode(translator) + " &= " + x86Instruction.Src.GetCode(translator)); break; case "call": if (x86Instruction.OperandCount != 1) { throw new WrongParameterException(x86Instruction); } if (x86Instruction.Dst.Type != OperandTypes.Label) { throw new WrongParameterException(x86Instruction); } string function = x86Instruction.Dst.GetCode(translator); if (!X86Assembler.IsFunction(function)) { throw new UnknownFunctionException(x86Instruction); } ps.AddCodeLine("vm." + x86Instruction.Dst.GetCode(translator) + "()"); break; case "cmp": if (x86Instruction.OperandCount != 2) { throw new WrongParameterException(x86Instruction); } if (x86Instruction.Src.Type == OperandTypes.Label) { throw new WrongParameterException(x86Instruction); } if (x86Instruction.Dst.Type == OperandTypes.Label) { throw new WrongParameterException(x86Instruction); } GenerateCmp(ps, x86Instruction.Dst.GetCode(translator), x86Instruction.Src.GetCode(translator)); break; case "jmp": case "je": case "jne": case "jg": case "jge": case "jl": case "jle": case "jz": case "jnz": case "loop": JumpInstruction(ps, assembly, x86Instruction); break; case "lea": if (x86Instruction.OperandCount != 2) { throw new WrongParameterException(x86Instruction); } if (x86Instruction.Dst.Type != OperandTypes.Register) { throw new WrongParameterException(x86Instruction); } if (x86Instruction.Src.Type == OperandTypes.Label) { ps.AddCodeLine(x86Instruction.Dst.GetCode(translator) + " = " + x86Instruction.Src.GetCode(translator)); break; } if (x86Instruction.Src.Type == OperandTypes.Memory) { ps.AddCodeLine(x86Instruction.Dst.GetCode(translator) + " = " + x86Instruction.Src.GetCode(addressTranslator)); break; } throw new WrongParameterException(x86Instruction); case "mov": if (x86Instruction.OperandCount != 2) { throw new WrongParameterException(x86Instruction); } if (x86Instruction.Dst.Type != OperandTypes.Memory && x86Instruction.Dst.Type != OperandTypes.Register) { throw new WrongParameterException(x86Instruction); } if (x86Instruction.Src.Type == OperandTypes.Label && !assembly.ConstantExists(((LabelArgument)x86Instruction.Src).Label)) { throw new WrongParameterException(x86Instruction); } ps.AddCodeLine(x86Instruction.Dst.GetCode(translator) + " = " + x86Instruction.Src.GetCode(translator)); break; case "mul": if (x86Instruction.OperandCount != 2) { throw new WrongParameterException(x86Instruction); } if (x86Instruction.Dst.Type != OperandTypes.Memory && x86Instruction.Dst.Type != OperandTypes.Register) { throw new WrongParameterException(x86Instruction); } if (x86Instruction.Src.Type == OperandTypes.Label) { throw new WrongParameterException(x86Instruction); } ps.AddCodeLine(x86Instruction.Dst.GetCode(translator) + " *= " + x86Instruction.Src.GetCode(translator)); break; case "or": if (x86Instruction.OperandCount != 2) { throw new WrongParameterException(x86Instruction); } if (x86Instruction.Dst.Type != OperandTypes.Memory && x86Instruction.Dst.Type != OperandTypes.Register) { throw new WrongParameterException(x86Instruction); } if (x86Instruction.Src.Type == OperandTypes.Label) { throw new WrongParameterException(x86Instruction); } ps.AddCodeLine(x86Instruction.Dst.GetCode(translator) + " |= " + x86Instruction.Src.GetCode(translator)); break; case "push": if (x86Instruction.OperandCount != 1) { throw new WrongParameterException(x86Instruction); } if (x86Instruction.Dst.Type != OperandTypes.Register) { throw new WrongParameterException(x86Instruction); } ps.AddCodeLine("vm.Push(" + x86Instruction.Dst.GetCode(translator) + ")"); break; case "pop": if (x86Instruction.OperandCount != 1) { throw new WrongParameterException(x86Instruction); } if (x86Instruction.Dst.Type != OperandTypes.Register) { throw new WrongParameterException(x86Instruction); } ps.AddCodeLine(x86Instruction.Dst.GetCode(translator) + " = vm.Pop()"); break; case "ret": if (x86Instruction.OperandCount != 0) { throw new WrongParameterException(x86Instruction); } ps.AddCodeLine("return;"); break; case "shl": if (x86Instruction.OperandCount != 2) { throw new WrongParameterException(x86Instruction); } if (x86Instruction.Dst.Type != OperandTypes.Memory && x86Instruction.Dst.Type != OperandTypes.Register) { throw new WrongParameterException(x86Instruction); } if (x86Instruction.Src.Type == OperandTypes.Label) { throw new WrongParameterException(x86Instruction); } ps.AddCodeLine(x86Instruction.Dst.GetCode(translator) + " <<= " + x86Instruction.Src.GetCode(translator)); break; case "shr": if (x86Instruction.OperandCount != 2) { throw new WrongParameterException(x86Instruction); } if (x86Instruction.Dst.Type != OperandTypes.Memory && x86Instruction.Dst.Type != OperandTypes.Register) { throw new WrongParameterException(x86Instruction); } if (x86Instruction.Src.Type == OperandTypes.Label) { throw new WrongParameterException(x86Instruction); } ps.AddCodeLine(x86Instruction.Dst.GetCode(translator) + " >>= " + x86Instruction.Src.GetCode(translator)); break; case "sub": if (x86Instruction.OperandCount != 2) { throw new WrongParameterException(x86Instruction); } if (x86Instruction.Dst.Type != OperandTypes.Memory && x86Instruction.Dst.Type != OperandTypes.Register) { throw new WrongParameterException(x86Instruction); } if (x86Instruction.Src.Type == OperandTypes.Label) { throw new WrongParameterException(x86Instruction); } ps.AddCodeLine(x86Instruction.Dst.GetCode(translator) + " -= " + x86Instruction.Src.GetCode(translator)); break; case "xor": if (x86Instruction.OperandCount != 2) { throw new WrongParameterException(x86Instruction); } if (x86Instruction.Dst.Type != OperandTypes.Memory && x86Instruction.Dst.Type != OperandTypes.Register) { throw new WrongParameterException(x86Instruction); } if (x86Instruction.Src.Type == OperandTypes.Label) { throw new WrongParameterException(x86Instruction); } ps.AddCodeLine(x86Instruction.Dst.GetCode(translator) + " ^= " + x86Instruction.Src.GetCode(translator)); break; } }
private void ps4KernelDlSymRetrieveSymbols(Byte[] buffer) { using (CapstoneX86Disassembler disassembler = CapstoneDisassembler.CreateX86Disassembler(X86DisassembleMode.Bit64)) { disassembler.EnableInstructionDetails = true; disassembler.DisassembleSyntax = DisassembleSyntax.Intel; //disassembler.EnableSkipDataMode = true; X86Instruction[] instructions = disassembler.Disassemble(buffer); int i = 0; foreach (X86Instruction instruction in instructions) { i++; X86Instruction lastInsn = (i > 1) ? instructions[i - 2] : null; long address = instruction.Address; X86InstructionId id = instruction.Id; String curr_instruction = GetInstructionTxt(instruction); String last_instruction = GetInstructionTxt(lastInsn); //if (address == 0x14362) // MessageBox.Show(curr_instruction); if (!instruction.IsSkippedData) { String ps4KernelDlSym = GetMemoryAddress((UInt64)ps4KernelDlSym_offset).ToString("x"); //if (instruction.Operand.Contains(ps4KernelDlSym)) // MessageBox.Show("call to ps4KernelDlSym: " + curr_instruction); //if(id == X86InstructionId.X86_INS_MOVABS) // MessageBox.Show("moveabs: " + curr_instruction); //MessageBox.Show(ps4KernelDlSym); if (instruction.Operand.Contains(ps4KernelDlSym) && id == X86InstructionId.X86_INS_MOVABS) { String ps4KernelDlSym_call = instructions[i + 1].Operand;//instructions[i + 1].Id == X86InstructionId.X86_INS_CALL ? string last_operand = lastInsn.Operand; if (lastInsn.Id == X86InstructionId.X86_INS_MOVABS) { String symbolReg = ""; var symbolName = ParseSymbolReference(lastInsn, out symbolReg); if (symbolName != "") { sympool.Add(lastInsn.Address, symbolName);//ps4KernelDlSym_Symbols.Add(symbolName); } // after we have got a symbol, find for near ps4KernelDlSym references var targetReg = instructions[i].Operand; var targetBytes = instructions[i].Bytes; //MessageBox.Show(targetReg); //MessageBox.Show(GetInstructionTxt(instructions[i+1])); for (int x = i + 2; x < instructions.Count(); x++) { var instruct = instructions[x]; if (instruct == null || instruct.IsSkippedData || instruct.Id == X86InstructionId.X86_INS_RET || instruct.Id == X86InstructionId.X86_INS_MOVABS & instruct.Operand.Split(',')[0] == targetReg)//GetInstructionTxt(instruct).Contains("ret")) { break; } if (instruct.Id == X86InstructionId.X86_INS_CALL)// && instruct.Operand == ps4KernelDlSym_call.Split(',')[0]) { //MessageBox.Show(GetInstructionTxt(instruct)); //MessageBox.Show(instruct.Operand + "\n\n" + ps4KernelDlSym_call); var reg = instruct.Operand; var prev_sym_reg = symbolReg; if (reg == targetReg & (symbolName = ParseSymbolReference(instructions[x - 1], out symbolReg)) != "") { if (targetBytes.SequenceEqual(instruct.Bytes))//if ((symbolName = ParseSymbolReference(instructions[x - 1], out symbolReg)) != "") { if (symbolReg == prev_sym_reg) { sympool.Add(instructions[x - 1].Address, symbolName); /* * var addr = GetMemoryAddress((ulong)instructions[x - 1].Address) - 0x1000; * Clipboard.SetText(addr.ToString("X2")); * MessageBox.Show("Addr: " + addr.ToString("X2") + ", " + symbolName + "\n\n" + GetInstructionTxt(instructions[x-1])); */ } //MessageBox.Show(last_instruction + "\n" + curr_instruction + "\n\n" + GetInstructionTxt(instructions[x-1]) + "\n" + GetInstructionTxt(instruct), "Near " + symbolName); } } //MessageBox.Show(curr_instruction + "\n" + GetInstructionTxt(instruct)); } //MessageBox.Show(last_instruction + "\n" + curr_instruction + "\n\n" + targetReg); } } /*else if (id == X86InstructionId.X86_INS_CALL) * { * MessageBox.Show(last_instruction + "\n" + curr_instruction); * }*/ } } } } }
public IntrinsicInfo(X86Instruction inst, IntrinsicType type) { Inst = inst; Type = type; }
/// <summary> /// Determines whether the specified <see cref="X86Instruction.OperandDescriptor"/> matches this /// <see cref="Operand"/>. /// </summary> /// <param name="descriptor">The <see cref="X86Instruction.OperandDescriptor"/> to match.</param> /// <returns><see langword="true"/> when the specified descriptor matches this operand; /// otherwise, <see langword="false"/>.</returns> internal override bool IsMatch(X86Instruction.OperandDescriptor descriptor) { switch (descriptor.OperandType) { case X86Instruction.OperandType.FarPointer: return this.Size == descriptor.Size; default: return false; } }
public X86InstructionListViewItem(X86Instruction instruction, byte[] bytes) { Instruction = instruction; Bytes = bytes; }
private static BaseOpcode ConvertToOpcode(X86Instruction instruction, ConditionCode conditionCode) { if (instruction == X86.Adc) { return(Opcode.Adc); } if (instruction == X86.Add) { return(Opcode.Add); } if (instruction == X86.Addsd) { return(Opcode.Addsd); } if (instruction == X86.Addss) { return(Opcode.Addss); } if (instruction == X86.And) { return(Opcode.And); } //if (instruction == X86.Break) return Opcode.Break; if (instruction == X86.Call) { return(Opcode.Call); } if (instruction == X86.Cdq) { return(Opcode.Cdq); } //if (instruction == X86.Cld) return Opcode.Cld; if (instruction == X86.Cli) { return(Opcode.Cli); } if (instruction == X86.Cmp) { return(Opcode.Cmp); } if (instruction == X86.CmpXchg) { return(Opcode.CmpXchg); } if (instruction == X86.Comisd) { return(Opcode.Comisd); } if (instruction == X86.Comiss) { return(Opcode.Comiss); } if (instruction == X86.CpuId) { return(Opcode.Cpuid); } if (instruction == X86.Cvtsd2ss) { return(Opcode.Cvtsd2ss); } if (instruction == X86.Cvtsi2sd) { return(Opcode.Cvtsi2sd); } if (instruction == X86.Cvtsi2ss) { return(Opcode.Cvtsi2ss); } if (instruction == X86.Cvtss2sd) { return(Opcode.Cvtss2sd); } if (instruction == X86.Cvttsd2si) { return(Opcode.Cvttsd2si); } if (instruction == X86.Cvttss2si) { return(Opcode.Cvttss2si); } if (instruction == X86.Dec) { return(Opcode.Dec); } if (instruction == X86.Div) { return(Opcode.Div); } if (instruction == X86.Divsd) { return(Opcode.Divsd); } if (instruction == X86.Divss) { return(Opcode.Divss); } if (instruction == X86.FarJmp) { return(Opcode.FarJmp); } if (instruction == X86.Fld) { return(Opcode.Fld); } if (instruction == X86.Hlt) { return(Opcode.Hlt); } if (instruction == X86.IDiv) { return(Opcode.Idiv); } if (instruction == X86.IMul) { return(Opcode.Imul); } if (instruction == X86.In) { return(Opcode.In); } if (instruction == X86.Inc) { return(Opcode.Inc); } //if (instruction == X86.Int) return Opcode.Int; //if (instruction == X86.Invlpg) return Opcode.Invlpg; if (instruction == X86.IRetd) { return(Opcode.Iretd); } if (instruction == X86.Jmp) { return(Opcode.Jmp); } if (instruction == X86.Lea) { return(Opcode.Lea); } //if (instruction == X86.Leave) return Opcode.Leave; if (instruction == X86.Lgdt) { return(Opcode.Lgdt); } if (instruction == X86.Lidt) { return(Opcode.Lidt); } //if (instruction == X86.Lock) return Opcode.Lock; if (instruction == X86.Mov) { return(Opcode.Mov); } if (instruction == X86.Movsd) { return(Opcode.Movsd); } if (instruction == X86.Movss) { return(Opcode.Movss); } if (instruction == X86.Movsx) { return(Opcode.Movsx); } if (instruction == X86.Movzx) { return(Opcode.Movzx); } if (instruction == X86.Mul) { return(Opcode.Mul); } if (instruction == X86.Mulsd) { return(Opcode.Mulsd); } if (instruction == X86.Mulss) { return(Opcode.Mulss); } if (instruction == X86.Neg) { return(Opcode.Neg); } if (instruction == X86.Nop) { return(Opcode.Nop); } if (instruction == X86.Not) { return(Opcode.Not); } if (instruction == X86.Or) { return(Opcode.Or); } if (instruction == X86.Out) { return(Opcode.Out); } //if (instruction == X86.Pause) return Opcode.Pause; if (instruction == X86.Pop) { return(Opcode.Pop); } if (instruction == X86.Popad) { return(Opcode.Popad); } if (instruction == X86.Popfd) { return(Opcode.Popfd); } if (instruction == X86.Push) { return(Opcode.Push); } if (instruction == X86.Pushad) { return(Opcode.Pushad); } if (instruction == X86.Pushfd) { return(Opcode.Pushfd); } if (instruction == X86.Rcr) { return(Opcode.Rcr); } //if (instruction == X86.Rdmsr) return Opcode.Rdmsr; //if (instruction == X86.Rdpmc) return Opcode.Rdpmc; //if (instruction == X86.Rdtsc) return Opcode.Rdtsc; //if (instruction == X86.Rep) return Opcode.Rep; if (instruction == X86.Ret) { return(Opcode.Ret); } if (instruction == X86.Roundsd) { return(Opcode.Roundsd); } if (instruction == X86.Roundss) { return(Opcode.Roundss); } if (instruction == X86.Sar) { return(Opcode.Sar); } if (instruction == X86.Sbb) { return(Opcode.Sbb); } if (instruction == X86.Shl) { return(Opcode.Shl); } if (instruction == X86.Shld) { return(Opcode.Shld); } if (instruction == X86.Shr) { return(Opcode.Shr); } if (instruction == X86.Shrd) { return(Opcode.Shrd); } if (instruction == X86.Sti) { return(Opcode.Sti); } if (instruction == X86.Pause) { return(Opcode.Pause); } //if (instruction == X86.Stos) return Opcode.Stos; if (instruction == X86.Sub) { return(Opcode.Sub); } if (instruction == X86.Subsd) { return(Opcode.Subsd); } if (instruction == X86.Subss) { return(Opcode.Subss); } if (instruction == X86.Xchg) { return(Opcode.Xchg); } if (instruction == X86.Xor) { return(Opcode.Xor); } if (instruction == X86.PXor) { return(Opcode.Pxor); } if (instruction == X86.MovCR) { return(Opcode.Mov); } if (instruction == X86.MovUPS) { return(Opcode.Movups); } if (instruction == X86.MovAPS) { return(Opcode.Movaps); } if (instruction == X86.Ucomisd) { return(Opcode.Ucomisd); } if (instruction == X86.Ucomiss) { return(Opcode.Ucomiss); } if (instruction == X86.Test) { return(Opcode.Test); } if (instruction == X86.Setcc) { return(ConvertSetInstruction(conditionCode)); } if (instruction == X86.Branch) { return(ConvertBranchInstruction(conditionCode)); } if (instruction == X86.Cmovcc) { return(ConvertConditionalMoveInstruction(conditionCode)); } if (instruction == X86.Bts) { return(Opcode.Bts); } if (instruction == X86.Btr) { return(Opcode.Btr); } if (instruction == X86.Lock) { return(Opcode.Lock); } if (instruction == X86.Break) { return(Opcode.InternalBreak); } return(null); }
/// <summary> /// Adjusts this <see cref="Operand"/> based on the specified /// <see cref="X86Instruction.OperandDescriptor"/>. /// </summary> /// <param name="descriptor">The <see cref="X86Instruction.OperandDescriptor"/> used to /// adjust.</param> /// <remarks> /// Only <see cref="X86Instruction.OperandDescriptor"/> instances for which <see cref="IsMatch"/> /// returns <see langword="true"/> may be used as a parameter to this method. /// </remarks> internal override void Adjust(X86Instruction.OperandDescriptor descriptor) { // Nothing to do. }
internal override void Adjust(X86Instruction.OperandDescriptor descriptor) { throw new NotImplementedException(); }
/// <summary> /// Adjusts this <see cref="Operand"/> based on the specified <see cref="X86Instruction.OperandDescriptor"/>. /// </summary> /// <param name="descriptor">The <see cref="X86Instruction.OperandDescriptor"/> used to adjust.</param> /// <remarks> /// Only <see cref="X86Instruction.OperandDescriptor"/> instances for which <see cref="IsMatch"/> returns /// <see langword="true"/> may be used as a parameter to this method. /// </remarks> void IConstructableOperand.Adjust(X86Instruction.OperandDescriptor descriptor) { this.Adjust(descriptor); }
internal override bool IsMatch(X86Instruction.OperandDescriptor descriptor) { throw new NotImplementedException(); }
/// <summary> /// Determines whether the specified <see cref="X86Instruction.OperandDescriptor"/> matches this /// <see cref="Operand"/>. /// </summary> /// <param name="descriptor">The <see cref="X86Instruction.OperandDescriptor"/> to match.</param> /// <returns><see langword="true"/> when the specified descriptor matches this operand; /// otherwise, <see langword="false"/>.</returns> internal override bool IsMatch(X86Instruction.OperandDescriptor descriptor) { switch (descriptor.OperandType) { case X86Instruction.OperandType.RegisterOperand: return descriptor.RegisterType.HasFlag(this.Register.GetRegisterType()); case X86Instruction.OperandType.FixedRegister: return this.Register == descriptor.FixedRegister; default: return false; } }
private void AssertEqual(string sExpected, X86Instruction instr) { var sActual = instr.ToString("N"); Assert.AreEqual(sExpected, sActual); }
/// <summary> /// Tests the given instruction. /// </summary> /// <param name="instruction">The <see cref="X86Instruction"/> instance to test.</param> /// <param name="nasmInstruction">The NASM string representation of the same instruction.</param> /// <param name="mode">The mode (16-bit, 32-bit or 64-bit) to use.</param> public void AssertInstruction(X86Instruction instruction, string nasmInstruction, DataSize mode) { #region Contract if (instruction == null) throw new ArgumentNullException("instruction"); if (nasmInstruction == null) throw new ArgumentNullException("nasmInstruction"); if (!Enum.IsDefined(typeof(DataSize), mode)) throw new InvalidEnumArgumentException("mode", (int)mode, typeof(DataSize)); if (mode != DataSize.Bit16 && mode != DataSize.Bit32 && mode != DataSize.Bit64) throw new ArgumentException(null, "mode"); #endregion var result = AssembleInstruction(instruction, nasmInstruction, mode); byte[] expected = result.Item1; byte[] actual = result.Item2; string expectedBytes = String.Join(", ", from b in expected select String.Format("0x{0:X2}", b)); string actualBytes = String.Join(", ", from b in actual select String.Format("0x{0:X2}", b)); Assert.AreEqual(expected, actual, String.Format("Expected {0}, actual {1}.", expectedBytes, actualBytes)); }
private void FloatCompare(Context context, X86Instruction instruction) { var result = context.Result; var left = context.Operand1; var right = context.Operand2; var condition = context.ConditionCode; // normalize condition switch (condition) { case ConditionCode.Equal: break; case ConditionCode.NotEqual: break; case ConditionCode.UnsignedGreaterOrEqual: condition = ConditionCode.GreaterOrEqual; break; case ConditionCode.UnsignedGreaterThan: condition = ConditionCode.GreaterThan; break; case ConditionCode.UnsignedLessOrEqual: condition = ConditionCode.LessOrEqual; break; case ConditionCode.UnsignedLessThan: condition = ConditionCode.LessThan; break; } Debug.Assert(!(left.IsR4 && right.IsR8)); Debug.Assert(!(left.IsR8 && right.IsR4)); switch (condition) { case ConditionCode.Equal: { // a==b // mov eax, 1 // ucomisd xmm0, xmm1 // jp L3 // jne L3 // ret //L3: // mov eax, 0 var newBlocks = CreateNewBlockContexts(2, context.Label); var nextBlock = Split(context); context.SetInstruction(X86.Mov32, result, CreateConstant(1)); context.AppendInstruction(instruction, null, left, right); context.AppendInstruction(X86.Branch, ConditionCode.Parity, newBlocks[1].Block); context.AppendInstruction(X86.Jmp, newBlocks[0].Block); newBlocks[0].AppendInstruction(X86.Branch, ConditionCode.NotEqual, newBlocks[1].Block); newBlocks[0].AppendInstruction(X86.Jmp, nextBlock.Block); newBlocks[1].AppendInstruction(X86.Mov32, result, ConstantZero32); newBlocks[1].AppendInstruction(X86.Jmp, nextBlock.Block); break; } case ConditionCode.NotEqual: { // a!=b // mov eax, 1 // ucomisd xmm0, xmm1 // jp L5 // setne al // movzx eax, al //L5: var newBlocks = CreateNewBlockContexts(1, context.Label); var nextBlock = Split(context); context.SetInstruction(X86.Mov32, result, CreateConstant(1)); context.AppendInstruction(instruction, null, left, right); context.AppendInstruction(X86.Branch, ConditionCode.Parity, nextBlock.Block); context.AppendInstruction(X86.Jmp, newBlocks[0].Block); newBlocks[0].AppendInstruction(X86.Setcc, ConditionCode.NotEqual, result); //newBlocks[0].AppendInstruction(X86.Movzx, InstructionSize.Size8, result, result); newBlocks[0].AppendInstruction(X86.Jmp, nextBlock.Block); break; } case ConditionCode.LessThan: { // a<b // mov eax, 0 // ucomisd xmm1, xmm0 // seta al context.SetInstruction(X86.Mov32, result, ConstantZero32); context.AppendInstruction(instruction, null, right, left); context.AppendInstruction(X86.Setcc, ConditionCode.UnsignedGreaterThan, result); break; } case ConditionCode.GreaterThan: { // a>b // mov eax, 0 // ucomisd xmm0, xmm1 // seta al context.SetInstruction(X86.Mov32, result, ConstantZero32); context.AppendInstruction(instruction, null, left, right); context.AppendInstruction(X86.Setcc, ConditionCode.UnsignedGreaterThan, result); break; } case ConditionCode.LessOrEqual: { // a<=b // mov eax, 0 // ucomisd xmm1, xmm0 // setae al context.SetInstruction(X86.Mov32, result, ConstantZero32); context.AppendInstruction(instruction, null, right, left); context.AppendInstruction(X86.Setcc, ConditionCode.UnsignedGreaterOrEqual, result); break; } case ConditionCode.GreaterOrEqual: { // a>=b // mov eax, 0 // ucomisd xmm0, xmm1 // setae al context.SetInstruction(X86.Mov32, result, ConstantZero32); context.AppendInstruction(instruction, null, left, right); context.AppendInstruction(X86.Setcc, ConditionCode.UnsignedGreaterOrEqual, result); break; } } }
/// <summary> /// Assembles the given instruction. /// </summary> /// <param name="instruction">The <see cref="X86Instruction"/> to assemble.</param> /// <param name="mode">The mode in which to assemble.</param> /// <returns>The bytes representing the assembled instruction.</returns> /// <exception cref="AssemblerException"> /// An assembler exception occurred. /// </exception> private byte[] Assemble(X86Instruction instruction, DataSize mode) { byte[] actual = null; BinObjectFileFormat format = new BinObjectFileFormat(); var arch = new X86Architecture(CpuType.AmdBulldozer, mode); BinObjectFile objectFile = (BinObjectFile)format.CreateObjectFile(arch, "test"); Section textSection = objectFile.Sections.AddNew(SectionType.Program); var text = textSection.Contents; text.Add(instruction); using (MemoryStream ms = new MemoryStream()) { using (BinaryWriter writer = new BinaryWriter(ms)) { objectFile.Format.CreateAssembler(objectFile).Assemble(writer); actual = ms.ToArray(); } } return actual; }
// tests the "expected utility maximization" tree walk and code manipulation // one descision tree node adds instructions and the second node (which is the child) adds and remove instructions void testUtilityAndSearch1() { prepare(); joinIrc1(); // instrumentation utilityCounter.reset(); systemTime = new Stopwatch(); systemTime.Start(); utilityAndSearchCpuTime = new Stopwatch(); utilityAndSearchCpuTime.Start(); mutatedProgram = new X86Program(); // set the utility function to one which calculates how useful the change of the mutated program is calcUtility = calcUtility_forMutatedProgram; ///--- // create and add children UtilityTreeElement var childrenPropabilityChangeAndNode = new List <Tuple <double, IArchitectureRecoverable, IUtilityTreeElement> >(); IArchitectureRecoverable recoverableProgramChange; int numberOfAddedInstrCandidates = 1000; // how many (randomly chose) candidate instructions are selected for this node and this run for (int iAddedInstrCandidate = 0; iAddedInstrCandidate < numberOfAddedInstrCandidates; iAddedInstrCandidate++) { var changeRecords = new RecoverableProgramChangeWithRecords <X86Instruction, X86Program, X86ExecutionContext> .ChangeRecords(); var createdChangeRecordAdd = new RecoverableProgramChangeWithRecords <X86Instruction, X86Program, X86ExecutionContext> .ChangeRecord( RecoverableProgramChangeWithRecords <X86Instruction, X86Program, X86ExecutionContext> .ChangeRecord.EnumType.ADD); changeRecords.arr.Add(createdChangeRecordAdd); int constMaxValue = 64; X86Instruction createdInstruction = new X86Instruction((X86Instruction.EnumInstructionType)rng.Next(0, X86Instruction.NUMBEROFINSTRUCTIONS)); createdInstruction.dest = rng.Next(0, 8); // for testing constant createdInstruction.a = rng.Next(0, constMaxValue); // for testing constant createdChangeRecordAdd.instructionToAdd = createdInstruction; recoverableProgramChange = new RecoverableProgramChangeWithRecords <X86Instruction, X86Program, X86ExecutionContext>(mutatedProgram, changeRecords); childrenPropabilityChangeAndNode.Add( new Tuple <double, IArchitectureRecoverable, IUtilityTreeElement>( 0.5, // TODO< calculate relative propability recoverableProgramChange, new NullUtilityTreeElement() // children of node ) ); } /* * changeRecords.arr.Add(createdChangeRecordAdd); * * X86Instruction createdInstruction = new X86Instruction((X86Instruction.EnumInstructionType)rng.Next(0, X86Instruction.NUMBEROFINSTRUCTIONS)); * createdInstruction.dest = 1; // for testing constant * createdInstruction.a = 1; // for testing constant * createdChangeRecordAdd.instructionToAdd = createdInstruction; */ if (false) // do we want to add DELETE changes { var changeRecords = new RecoverableProgramChangeWithRecords <X86Instruction, X86Program, X86ExecutionContext> .ChangeRecords(); changeRecords.arr.Add(new RecoverableProgramChangeWithRecords <X86Instruction, X86Program, X86ExecutionContext> .ChangeRecord(RecoverableProgramChangeWithRecords <X86Instruction, X86Program, X86ExecutionContext> .ChangeRecord.EnumType.REMOVE)); changeRecords.arr[0].idxSource = 0; recoverableProgramChange = new RecoverableProgramChangeWithRecords <X86Instruction, X86Program, X86ExecutionContext>( mutatedProgram, changeRecords); childrenPropabilityChangeAndNode.Add( new Tuple <double, IArchitectureRecoverable, IUtilityTreeElement>( 0.5, // TODO< calculate relative propability recoverableProgramChange, new NullUtilityTreeElement() // children of node ) ); } ProgramChangeBranchUtilityTreeElement treeElementChildren = new ProgramChangeBranchUtilityTreeElement( 1.0, // propability childrenPropabilityChangeAndNode ); ///--- // create and add root UtilityTreeElement childrenPropabilityChangeAndNode = new List <Tuple <double, IArchitectureRecoverable, IUtilityTreeElement> >(); for (int iAddedInstrCandidate = 0; iAddedInstrCandidate < numberOfAddedInstrCandidates; iAddedInstrCandidate++) { var changeRecords = new RecoverableProgramChangeWithRecords <X86Instruction, X86Program, X86ExecutionContext> .ChangeRecords(); var createdChangeRecordAdd = new RecoverableProgramChangeWithRecords <X86Instruction, X86Program, X86ExecutionContext> . ChangeRecord( RecoverableProgramChangeWithRecords <X86Instruction, X86Program, X86ExecutionContext> .ChangeRecord.EnumType.ADD); changeRecords.arr.Add(createdChangeRecordAdd); int constMaxValue = 64; X86Instruction createdInstruction = new X86Instruction((X86Instruction.EnumInstructionType)rng.Next(0, X86Instruction.NUMBEROFINSTRUCTIONS)); createdInstruction.dest = rng.Next(0, 8); // for testing constant createdInstruction.a = rng.Next(0, constMaxValue); // for testing constant createdChangeRecordAdd.instructionToAdd = createdInstruction; recoverableProgramChange = new RecoverableProgramChangeWithRecords <X86Instruction, X86Program, X86ExecutionContext>(mutatedProgram, changeRecords); childrenPropabilityChangeAndNode.Add( new Tuple <double, IArchitectureRecoverable, IUtilityTreeElement>( 0.5, // TODO< calculate relative propability recoverableProgramChange, treeElementChildren // children of node ) ); } ProgramChangeBranchUtilityTreeElement treeElementRoot = new ProgramChangeBranchUtilityTreeElement( 1.0, // propability childrenPropabilityChangeAndNode ); var pathsWithPropabilities = returnPathWithPropabilities(treeElementRoot); double highestExpectedUtility = 0.00000000000000001; // we set it to almost zero because we assume an utility function which returns in the range [0 ... inf) // double.NaN; int[] pathOfHighestExpectedUtility = null; foreach (var iPathWithPropability in pathsWithPropabilities) { int[] path = iPathWithPropability.Item1; double propability = iPathWithPropability.Item2; if (false) { log("expectedUtilityMaximization", string.Join(",", path)); } double expectedUtility = propability * calcUtilityFunction(path, returnUtility(path)); if (pathOfHighestExpectedUtility == null || expectedUtility > highestExpectedUtility) { highestExpectedUtility = expectedUtility; pathOfHighestExpectedUtility = path; } } if (true) { log("expectedUtilityMaximization.instrumentation.counter", "=" + utilityCounter.count.ToString()); } if (pathOfHighestExpectedUtility != null) { log("expectedUtilityMaximization", "path found with the highest utility"); } int debugHere = 5; }
/// <summary> /// Tests the given instruction. /// </summary> /// <param name="instruction">The <see cref="X86Instruction"/> instance to test.</param> /// <param name="expected">The expected result.</param> private void AssertXBitInstruction(X86Instruction instruction, byte[] expected, DataSize mode) { #region Contract if (instruction == null) throw new ArgumentNullException("instruction"); if (expected == null) throw new ArgumentNullException("expected"); #endregion byte[] actual = Assemble(instruction, mode); string expectedBytes = String.Join(" ", from b in expected select String.Format("{0:X2}", b)); string actualBytes = String.Join(" ", from b in actual select String.Format("{0:X2}", b)); Assert.AreEqual(expected, actual, String.Format("Expected {0}, got {1}.", expectedBytes, actualBytes)); }
static void Add(X86Instruction inst, in InstructionInfo info)
/// <summary> /// Tests that the given instruction fails. /// </summary> /// <param name="instruction">The <see cref="X86Instruction"/> instance to test.</param> public void Assert32BitInstructionFails(X86Instruction instruction) { AssertXBitInstructionFails(instruction, DataSize.Bit32); }
public static bool SupportsVexPrefix(X86Instruction inst) { return(_instTable[(int)inst].Flags.HasFlag(InstructionFlags.Vex)); }
/// <summary> /// Adjusts this <see cref="Operand"/> based on the specified <see cref="X86Instruction.OperandDescriptor"/>. /// </summary> /// <param name="descriptor">The <see cref="X86Instruction.OperandDescriptor"/> used to adjust.</param> /// <remarks> /// Only <see cref="X86Instruction.OperandDescriptor"/> instances for which <see cref="IsMatch"/> returns /// <see langword="true"/> may be used as a parameter to this method. /// </remarks> internal override void Adjust(X86Instruction.OperandDescriptor descriptor) { this.asExtraImmediate = (descriptor.OperandEncoding == X86Instruction.OperandEncoding.ExtraImmediate); Contract.Assume(this.PreferredSize == DataSize.None || this.PreferredSize <= descriptor.Size); this.PreferredSize = descriptor.Size; }
/// <summary> /// Floating point compare instruction. /// </summary> /// <param name="context">The context.</param> private void FloatCompare(Context context) { Operand result = context.Result; Operand left = context.Operand1; Operand right = context.Operand2; ConditionCode condition = context.ConditionCode; // normalize condition switch (condition) { case ConditionCode.Equal: break; case ConditionCode.NotEqual: break; case ConditionCode.UnsignedGreaterOrEqual: condition = ConditionCode.GreaterOrEqual; break; case ConditionCode.UnsignedGreaterThan: condition = ConditionCode.GreaterThan; break; case ConditionCode.UnsignedLessOrEqual: condition = ConditionCode.LessOrEqual; break; case ConditionCode.UnsignedLessThan: condition = ConditionCode.LessThan; break; } // TODO - Move the following to its own pre-IR decomposition stage for this instruction // Swap, if necessary, the operands to place register operand first than memory operand // otherwise the memory operand will have to be loaded into a register if ((condition == ConditionCode.Equal || condition == ConditionCode.NotEqual) && left.IsMemoryAddress && !right.IsMemoryAddress) { // swap order of operands to move var t = left; left = right; right = t; } Context before = context.InsertBefore(); // Compare using the smallest precision if (left.IsR4 && right.IsR8) { Operand rop = AllocateVirtualRegister(TypeSystem.BuiltIn.R4); before.SetInstruction(X86.Cvtsd2ss, rop, right); right = rop; } if (left.IsR8 && right.IsR4) { Operand rop = AllocateVirtualRegister(TypeSystem.BuiltIn.R4); before.SetInstruction(X86.Cvtsd2ss, rop, left); left = rop; } X86Instruction instruction = null; InstructionSize size = InstructionSize.None; if (left.IsR4) { instruction = X86.Ucomiss; size = InstructionSize.Size32; } else { instruction = X86.Ucomisd; size = InstructionSize.Size64; } switch (condition) { case ConditionCode.Equal: { // a==b // mov eax, 1 // ucomisd xmm0, xmm1 // jp L3 // jne L3 // ret //L3: // mov eax, 0 var newBlocks = CreateNewBlockContexts(2); Context nextBlock = Split(context); context.SetInstruction(X86.Mov, result, Operand.CreateConstant(TypeSystem, 1)); context.AppendInstruction(instruction, size, null, left, right); context.AppendInstruction(X86.Branch, ConditionCode.Parity, newBlocks[1].Block); context.AppendInstruction(X86.Jmp, newBlocks[0].Block); newBlocks[0].AppendInstruction(X86.Branch, ConditionCode.NotEqual, newBlocks[1].Block); newBlocks[0].AppendInstruction(X86.Jmp, nextBlock.Block); newBlocks[1].AppendInstruction(X86.Mov, result, ConstantZero); newBlocks[1].AppendInstruction(X86.Jmp, nextBlock.Block); break; } case ConditionCode.NotEqual: { // a!=b // mov eax, 1 // ucomisd xmm0, xmm1 // jp L5 // setne al // movzx eax, al //L5: var newBlocks = CreateNewBlockContexts(1); Context nextBlock = Split(context); context.SetInstruction(X86.Mov, result, Operand.CreateConstant(TypeSystem, 1)); context.AppendInstruction(instruction, size, null, left, right); context.AppendInstruction(X86.Branch, ConditionCode.Parity, nextBlock.Block); context.AppendInstruction(X86.Jmp, newBlocks[0].Block); newBlocks[0].AppendInstruction(X86.Setcc, ConditionCode.NotEqual, result); newBlocks[0].AppendInstruction(X86.Movzx, InstructionSize.Size8, result, result); newBlocks[0].AppendInstruction(X86.Jmp, nextBlock.Block); break; } case ConditionCode.LessThan: { // a<b // mov eax, 0 // ucomisd xmm1, xmm0 // seta al context.SetInstruction(X86.Mov, result, ConstantZero); context.AppendInstruction(instruction, size, null, right, left); context.AppendInstruction(X86.Setcc, ConditionCode.UnsignedGreaterThan, result); break; } case ConditionCode.GreaterThan: { // a>b // mov eax, 0 // ucomisd xmm0, xmm1 // seta al context.SetInstruction(X86.Mov, result, ConstantZero); context.AppendInstruction(instruction, size, null, left, right); context.AppendInstruction(X86.Setcc, ConditionCode.UnsignedGreaterThan, result); break; } case ConditionCode.LessOrEqual: { // a<=b // mov eax, 0 // ucomisd xmm1, xmm0 // setae al context.SetInstruction(X86.Mov, result, ConstantZero); context.AppendInstruction(instruction, size, null, right, left); context.AppendInstruction(X86.Setcc, ConditionCode.UnsignedGreaterOrEqual, result); break; } case ConditionCode.GreaterOrEqual: { // a>=b // mov eax, 0 // ucomisd xmm0, xmm1 // setae al context.SetInstruction(X86.Mov, result, ConstantZero); context.AppendInstruction(instruction, size, null, left, right); context.AppendInstruction(X86.Setcc, ConditionCode.UnsignedGreaterOrEqual, result); break; } } }
private void MoveFloatingPoint(Context context, X86Instruction instruction) { Operand xmm0 = Operand.CreateCPURegister(context.Result.Type, SSE2Register.XMM0); Operand result = context.Result; Operand operand = context.Operand1; context.SetInstruction(instruction, xmm0, operand); context.AppendInstruction(instruction, result, xmm0); }
public WrongParameterException(X86Instruction x86Instruction) : base("Wrong parameters for instruction " + x86Instruction.Name + " at line: " + x86Instruction.Line + ".") { X86Instruction = x86Instruction; }
/// <summary> /// Determines whether the specified <see cref="X86Instruction.OperandDescriptor"/> matches this /// <see cref="Operand"/>. /// </summary> /// <param name="descriptor">The <see cref="X86Instruction.OperandDescriptor"/> to match.</param> /// <returns><see langword="true"/> when the specified descriptor matches this operand; /// otherwise, <see langword="false"/>.</returns> internal override bool IsMatch(X86Instruction.OperandDescriptor descriptor) { switch (descriptor.OperandType) { case X86Instruction.OperandType.RegisterOrMemoryOperand: return this.Size == descriptor.RegisterType.GetSize(); case X86Instruction.OperandType.MemoryOperand: return this.Size == descriptor.Size; default: return false; } }
public UnknownFunctionException(X86Instruction x86Instruction) : base("Unknown function" + x86Instruction.Dst + " at line: " + x86Instruction.Line + ".") { X86Instruction = x86Instruction; }
/// <summary> /// Determines whether the specified <see cref="X86Instruction.OperandDescriptor"/> matches this /// <see cref="Operand"/>. /// </summary> /// <param name="descriptor">The <see cref="X86Instruction.OperandDescriptor"/> to match.</param> /// <returns><see langword="true"/> when the specified descriptor matches this operand; /// otherwise, <see langword="false"/>.</returns> bool IConstructableOperand.IsMatch(X86Instruction.OperandDescriptor descriptor) { return this.IsMatch(descriptor); }
public void test() { targetProgram = new X86Instruction[3]; /* * targetProgram[0] = new Instruction(); * targetProgram[0].type = Instruction.EnumInstructionType.ADD_INTCONST; * targetProgram[0].dest = 0; * targetProgram[0].a = 4; * * targetProgram[1] = new Instruction(); * targetProgram[1].type = Instruction.EnumInstructionType.ADD_INTCONST; * targetProgram[1].dest = 0; * targetProgram[1].a = 4; * * targetProgram[2] = new Instruction(); * targetProgram[2].type = Instruction.EnumInstructionType.MUL_INT; * targetProgram[2].dest = 0; * targetProgram[2].a = 1; * * targetProgram[3] = new Instruction(); * targetProgram[3].type = Instruction.EnumInstructionType.MOV_INTINT; * targetProgram[3].dest = 1; * targetProgram[3].a = 0; */ targetProgram[0] = new X86Instruction(X86Instruction.EnumInstructionType.MUL_FLOATVECTOR4); targetProgram[0].dest = 0; targetProgram[0].a = 0; targetProgram[1] = new X86Instruction(X86Instruction.EnumInstructionType.HORIZONTALADD_FLOATVECTOR4); targetProgram[1].dest = 0; targetProgram[1].a = 0; targetProgram[2] = new X86Instruction(X86Instruction.EnumInstructionType.HORIZONTALADD_FLOATVECTOR4); targetProgram[2].dest = 0; targetProgram[2].a = 0; instructionEnumeration = new int[3 * widthOfInstructionEncoding]; maximalValue = new int[3 * widthOfInstructionEncoding]; maximalValue[0 * widthOfInstructionEncoding + 0] = 4; // immediate2 maximalValue[0 * widthOfInstructionEncoding + 1] = numberOfInstructions; // type maximalValue[0 * widthOfInstructionEncoding + 2] = 8; // dest maximalValue[0 * widthOfInstructionEncoding + 3] = 64; // source/immediate maximalValue[1 * widthOfInstructionEncoding + 0] = 4; // immediate2 maximalValue[1 * widthOfInstructionEncoding + 1] = numberOfInstructions; // type maximalValue[1 * widthOfInstructionEncoding + 2] = 8; // dest maximalValue[1 * widthOfInstructionEncoding + 3] = 64; // source/immediate maximalValue[2 * widthOfInstructionEncoding + 0] = 4; // immediate2 maximalValue[2 * widthOfInstructionEncoding + 1] = numberOfInstructions; // type maximalValue[2 * widthOfInstructionEncoding + 2] = 8; // dest maximalValue[2 * widthOfInstructionEncoding + 3] = 64; // source/immediate for (;;) { enumerateStep(); } }
/// <summary> /// Determines whether the specified <see cref="X86Instruction.OperandDescriptor"/> matches this /// <see cref="Operand"/>. /// </summary> /// <param name="descriptor">The <see cref="X86Instruction.OperandDescriptor"/> to match.</param> /// <returns><see langword="true"/> when the specified descriptor matches this operand; /// otherwise, <see langword="false"/>.</returns> internal abstract bool IsMatch(X86Instruction.OperandDescriptor descriptor);
/// <summary> /// Adjusts this <see cref="Operand"/> based on the specified /// <see cref="X86Instruction.OperandDescriptor"/>. /// </summary> /// <param name="descriptor">The <see cref="X86Instruction.OperandDescriptor"/> used to /// adjust.</param> /// <remarks> /// Only <see cref="X86Instruction.OperandDescriptor"/> instances for which <see cref="IsMatch"/> /// returns <see langword="true"/> may be used as a parameter to this method. /// </remarks> internal override void Adjust(X86Instruction.OperandDescriptor descriptor) { // When the operand needs to be added to the opcode, set it as such. if (descriptor.OperandEncoding == X86Instruction.OperandEncoding.OpcodeAdd) this.Encoding = OperandEncoding.AddToOpcode; else if (descriptor.OperandType == X86Instruction.OperandType.FixedRegister) this.Encoding = OperandEncoding.Ignore; else this.Encoding = OperandEncoding.Default; }