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.
7 #define NEEDSNACLINSTTYPESTRING
9 #include "native_client/src/trusted/validator/x86/decoder/generator/modeled_nacl_inst.h"
13 void NaClSetOpcodeInModRm(uint8_t value, uint8_t *opcode_ext) {
17 void NaClSetOpcodeInModRmRm(uint8_t value, uint8_t *opcode_ext) {
18 *opcode_ext += (value << 4);
21 void NaClSetOpcodePlusR(uint8_t value, uint8_t *opcode_ext) {
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.
28 static void NaClPrintAddOperandFlag(struct Gio* f,
31 const char* flag_name) {
32 if (op->flags & NACL_OPFLAG(flag)) {
33 gprintf(f, "%s", flag_name);
37 void NaClModeledInstPrint(struct Gio* f, const NaClModeledInst* inst) {
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);
45 count += prefix_len + 1;
49 /* Add opcode bytes. */
50 for (i = 0; i < inst->num_opcode_bytes; ++i) {
55 gprintf(f,"%02x", inst->opcode[i]);
58 if (inst->flags & NACL_IFLAG(OpcodeInModRm)) {
59 gprintf(f, " / %d", NaClGetOpcodeInModRm(inst->opcode_ext));
61 } else if (inst->flags & NACL_IFLAG(OpcodePlusR)) {
62 gprintf(f, " - r%d", NaClGetOpcodePlusR(inst->opcode_ext));
65 if (inst->flags & NACL_IFLAG(OpcodeInModRmRm)) {
66 gprintf(f, " / %d", NaClGetOpcodeInModRmRm(inst->opcode_ext));
73 { /* Print out instruction type less the NACLi_ prefix. */
74 const char* name = NaClInstTypeString(inst->insttype);
75 gprintf(f, "%s ", name + strlen("NACLi_"));
77 if (inst->flags) NaClIFlagsPrint(f, inst->flags);
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.
84 if ((NACLi_INVALID != inst->insttype) ||
85 ((inst->flags & NACL_IFLAG(Opcode0F0F)))) {
90 /* Instruction has been simplified. Print out corresponding
91 * hints to the reader, so that they know that the instruction
92 * has been simplified.
94 if (NaClHasBit(inst->flags, NACL_IFLAG(PartialInstruction))) {
97 gprintf(f, "%s", NaClMnemonicName(inst->name));
99 /* If an instruction has been simplified, and it illegal, communicate
100 * that in the printed modeled instruction.
102 if (NaClHasBit(inst->flags, NACL_IFLAG(NaClIllegal)) &&
103 NaClHasBit(inst->flags, NACL_IFLAG(PartialInstruction))) {
104 gprintf(f, "(illegal)");
106 for (i = 0; i < inst->num_operands; ++i) {
107 if (NULL == inst->operands[i].format_string) continue;
113 gprintf(f, " %s", inst->operands[i].format_string);
115 /* If this is a partial instruction, add set/use information
116 * so that that it is more clear what was matched.
118 if (NaClHasBit(inst->flags, NACL_IFLAG(PartialInstruction))) {
119 const NaClOp* op = inst->operands + i;
120 if (NaClHasBit(op->flags, (NACL_OPFLAG(OpSet) |
122 NACL_OPFLAG(OperandZeroExtends_v)))) {
124 NaClPrintAddOperandFlag(f, op, OpSet, "s");
125 NaClPrintAddOperandFlag(f, op, OpUse, "u");
126 NaClPrintAddOperandFlag(f, op, OperandZeroExtends_v, "z");
132 /* Now print actual encoding of each operand. */
133 for (i = 0; i < inst->num_operands; ++i) {
135 NaClOpPrint(f, inst->operands + i);