| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. | |
| 3 * Use of this source code is governed by a BSD-style license that can be | |
| 4 * found in the LICENSE file. | |
| 5 */ | |
| 6 | |
| 7 #define NEEDSNACLINSTTYPESTRING | |
| 8 | |
| 9 #include "native_client/src/trusted/validator/x86/decoder/generator/modeled_nacl
_inst.h" | |
| 10 | |
| 11 #include <string.h> | |
| 12 | |
| 13 void NaClSetOpcodeInModRm(uint8_t value, uint8_t *opcode_ext) { | |
| 14 *opcode_ext += value; | |
| 15 } | |
| 16 | |
| 17 void NaClSetOpcodeInModRmRm(uint8_t value, uint8_t *opcode_ext) { | |
| 18 *opcode_ext += (value << 4); | |
| 19 } | |
| 20 | |
| 21 void NaClSetOpcodePlusR(uint8_t value, uint8_t *opcode_ext) { | |
| 22 *opcode_ext += value; | |
| 23 } | |
| 24 | |
| 25 /* Print the flag name if the flag is defined for the corresponding operand. | |
| 26 * Used to print out set/use/zero extend information for partial instructions. | |
| 27 */ | |
| 28 static void NaClPrintAddOperandFlag(struct Gio* f, | |
| 29 const NaClOp* op, | |
| 30 NaClOpFlag flag, | |
| 31 const char* flag_name) { | |
| 32 if (op->flags & NACL_OPFLAG(flag)) { | |
| 33 gprintf(f, "%s", flag_name); | |
| 34 } | |
| 35 } | |
| 36 | |
| 37 void NaClModeledInstPrint(struct Gio* f, const NaClModeledInst* inst) { | |
| 38 int i; | |
| 39 int count = 2; | |
| 40 /* Add prefix bytes if defined by prefix. */ | |
| 41 const char* prefix = OpcodePrefixBytes(inst->prefix); | |
| 42 int prefix_len = (int) strlen(prefix); | |
| 43 gprintf(f, " %s", prefix); | |
| 44 if (prefix_len > 0) { | |
| 45 count += prefix_len + 1; | |
| 46 gprintf(f, " "); | |
| 47 } | |
| 48 | |
| 49 /* Add opcode bytes. */ | |
| 50 for (i = 0; i < inst->num_opcode_bytes; ++i) { | |
| 51 if (i > 0) { | |
| 52 gprintf(f, " "); | |
| 53 ++count; | |
| 54 } | |
| 55 gprintf(f,"%02x", inst->opcode[i]); | |
| 56 count += 2; | |
| 57 } | |
| 58 if (inst->flags & NACL_IFLAG(OpcodeInModRm)) { | |
| 59 gprintf(f, " / %d", NaClGetOpcodeInModRm(inst->opcode_ext)); | |
| 60 count += 4; | |
| 61 } else if (inst->flags & NACL_IFLAG(OpcodePlusR)) { | |
| 62 gprintf(f, " - r%d", NaClGetOpcodePlusR(inst->opcode_ext)); | |
| 63 count += 5; | |
| 64 } | |
| 65 if (inst->flags & NACL_IFLAG(OpcodeInModRmRm)) { | |
| 66 gprintf(f, " / %d", NaClGetOpcodeInModRmRm(inst->opcode_ext)); | |
| 67 count += 4; | |
| 68 } | |
| 69 while (count < 30) { | |
| 70 gprintf(f, " "); | |
| 71 ++count; | |
| 72 } | |
| 73 { /* Print out instruction type less the NACLi_ prefix. */ | |
| 74 const char* name = NaClInstTypeString(inst->insttype); | |
| 75 gprintf(f, "%s ", name + strlen("NACLi_")); | |
| 76 } | |
| 77 if (inst->flags) NaClIFlagsPrint(f, inst->flags); | |
| 78 gprintf(f, "\n"); | |
| 79 | |
| 80 /* If instruction type is invalid, and doesn't have | |
| 81 * special translation purposes, then don't print additional | |
| 82 * (ignored) information stored in the modeled instruction. | |
| 83 */ | |
| 84 if ((NACLi_INVALID != inst->insttype) || | |
| 85 ((inst->flags & NACL_IFLAG(Opcode0F0F)))) { | |
| 86 Bool is_first = TRUE; | |
| 87 int i; | |
| 88 gprintf(f, " "); | |
| 89 | |
| 90 /* Instruction has been simplified. Print out corresponding | |
| 91 * hints to the reader, so that they know that the instruction | |
| 92 * has been simplified. | |
| 93 */ | |
| 94 if (NaClHasBit(inst->flags, NACL_IFLAG(PartialInstruction))) { | |
| 95 gprintf(f, "[P] "); | |
| 96 } | |
| 97 gprintf(f, "%s", NaClMnemonicName(inst->name)); | |
| 98 | |
| 99 /* If an instruction has been simplified, and it illegal, communicate | |
| 100 * that in the printed modeled instruction. | |
| 101 */ | |
| 102 if (NaClHasBit(inst->flags, NACL_IFLAG(NaClIllegal)) && | |
| 103 NaClHasBit(inst->flags, NACL_IFLAG(PartialInstruction))) { | |
| 104 gprintf(f, "(illegal)"); | |
| 105 } | |
| 106 for (i = 0; i < inst->num_operands; ++i) { | |
| 107 if (NULL == inst->operands[i].format_string) continue; | |
| 108 if (is_first) { | |
| 109 is_first = FALSE; | |
| 110 } else { | |
| 111 gprintf(f, ","); | |
| 112 } | |
| 113 gprintf(f, " %s", inst->operands[i].format_string); | |
| 114 | |
| 115 /* If this is a partial instruction, add set/use information | |
| 116 * so that that it is more clear what was matched. | |
| 117 */ | |
| 118 if (NaClHasBit(inst->flags, NACL_IFLAG(PartialInstruction))) { | |
| 119 const NaClOp* op = inst->operands + i; | |
| 120 if (NaClHasBit(op->flags, (NACL_OPFLAG(OpSet) | | |
| 121 NACL_OPFLAG(OpUse) | | |
| 122 NACL_OPFLAG(OperandZeroExtends_v)))) { | |
| 123 gprintf(f, " ("); | |
| 124 NaClPrintAddOperandFlag(f, op, OpSet, "s"); | |
| 125 NaClPrintAddOperandFlag(f, op, OpUse, "u"); | |
| 126 NaClPrintAddOperandFlag(f, op, OperandZeroExtends_v, "z"); | |
| 127 gprintf(f, ")"); | |
| 128 } | |
| 129 } | |
| 130 } | |
| 131 gprintf(f, "\n"); | |
| 132 /* Now print actual encoding of each operand. */ | |
| 133 for (i = 0; i < inst->num_operands; ++i) { | |
| 134 gprintf(f, " "); | |
| 135 NaClOpPrint(f, inst->operands + i); | |
| 136 } | |
| 137 } | |
| 138 } | |
| OLD | NEW |