For most instructions, instruction_index == operand_index, but some instructions (floating point, some others) have an implicit first operand (st0), so we have to remap things a bit Instruction index represents the 'nth' argument/opcode in the instruction, whereas the operand index is index that XED holds that operand in the instruction
| 252 | // For most instructions, instruction_index == operand_index, but some instructions (floating point, some others) have an implicit first operand (st0), so we have to remap things a bit |
| 253 | // Instruction index represents the 'nth' argument/opcode in the instruction, whereas the operand index is index that XED holds that operand in the instruction |
| 254 | static size_t ReadFloatILOperand(LowLevelILFunction& il, const xed_decoded_inst_t* xedd, const size_t addr, const size_t instruction_index, const size_t operand_index, size_t opLen = 10) |
| 255 | { |
| 256 | const unsigned int operandSize = xed_decoded_inst_operand_length_bits(xedd, (unsigned)operand_index) / 8; |
| 257 | const xed_operand_enum_t op_name = xed_operand_name(xed_inst_operand(xed_decoded_inst_inst(xedd), (unsigned)operand_index)); |
| 258 | |
| 259 | switch (op_name) |
| 260 | { |
| 261 | // Register cases |
| 262 | case XED_OPERAND_REG0: |
| 263 | case XED_OPERAND_REG1: |
| 264 | case XED_OPERAND_REG2: |
| 265 | case XED_OPERAND_REG3: |
| 266 | case XED_OPERAND_REG4: |
| 267 | case XED_OPERAND_REG5: |
| 268 | case XED_OPERAND_REG6: |
| 269 | case XED_OPERAND_REG7: |
| 270 | case XED_OPERAND_REG8: |
| 271 | case XED_OPERAND_BASE0: |
| 272 | case XED_OPERAND_BASE1: |
| 273 | return il.Operand(instruction_index, il.Register(operandSize, (uint32_t)xed_decoded_inst_get_reg(xedd, op_name))); |
| 274 | |
| 275 | // Immediates |
| 276 | case XED_OPERAND_IMM0: |
| 277 | case XED_OPERAND_PTR: |
| 278 | case XED_OPERAND_RELBR: |
| 279 | if (xed_decoded_inst_get_immediate_is_signed(xedd)) |
| 280 | return il.Operand(instruction_index, il.FloatConvert(opLen, il.FloatConstRaw(operandSize, xed_decoded_inst_get_signed_immediate(xedd)))); |
| 281 | else |
| 282 | return il.Operand(instruction_index, il.FloatConvert(opLen, il.FloatConstRaw(operandSize, xed_decoded_inst_get_unsigned_immediate(xedd)))); |
| 283 | case XED_OPERAND_IMM1: |
| 284 | return il.Operand(instruction_index, il.FloatConvert(opLen, il.FloatConstRaw(operandSize, xed_decoded_inst_get_second_immediate(xedd)))); |
| 285 | |
| 286 | // Memory Acesses |
| 287 | case XED_OPERAND_AGEN: |
| 288 | case XED_OPERAND_MEM0: |
| 289 | case XED_OPERAND_MEM1: // In what case would the memory address size be 10?? (floating point ops?) |
| 290 | if (operandSize != opLen) |
| 291 | return il.Operand(instruction_index, il.FloatConvert(opLen, il.Load(operandSize, GetILOperandMemoryAddress(il, xedd, addr, instruction_index, operand_index)))); |
| 292 | return il.Operand(instruction_index, il.Load(opLen, GetILOperandMemoryAddress(il, xedd, addr, instruction_index, operand_index))); |
| 293 | |
| 294 | default: |
| 295 | return il.Undefined(); |
| 296 | } |
| 297 | } |
| 298 | |
| 299 | |
| 300 | // For most instructions, instruction_index == operand_index, but some instructions (floating point, some others) have an implicit first operand (st0), so we have to remap things a bit |
no test coverage detected