| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. | 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 | 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 /* Some useful utilities for validator patterns. */ | 7 /* Some useful utilities for validator patterns. */ |
| 8 | 8 |
| 9 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/ncvalidate_utils
.h" | 9 #include "native_client/src/trusted/validator/x86/ncval_reg_sfi/ncvalidate_utils
.h" |
| 10 | 10 |
| 11 #include "native_client/src/shared/platform/nacl_log.h" | 11 #include "native_client/src/shared/platform/nacl_log.h" |
| 12 #include "native_client/src/trusted/validator/x86/decoder/nc_decode_tables.h" | 12 #include "native_client/src/trusted/validator/x86/decoder/nc_decode_tables.h" |
| 13 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_state_internal
.h" | 13 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_state_internal
.h" |
| 14 #include "native_client/src/trusted/validator/x86/decoder/ncop_exps.h" | |
| 15 | 14 |
| 16 /* To turn on debugging of instruction decoding, change value of | 15 /* To turn on debugging of instruction decoding, change value of |
| 17 * DEBUGGING to 1. | 16 * DEBUGGING to 1. |
| 18 */ | 17 */ |
| 19 #define DEBUGGING 0 | 18 #define DEBUGGING 0 |
| 20 | 19 |
| 21 #include "native_client/src/shared/utils/debugging.h" | 20 #include "native_client/src/shared/utils/debugging.h" |
| 22 | 21 |
| 22 #include "native_client/src/trusted/validator/x86/decoder/ncopcode_desc_inl.c" |
| 23 #include "native_client/src/trusted/validator/x86/decoder/ncop_exps_inl.c" |
| 24 |
| 23 const NaClOpFlags NaClOpSetOrUse = NACL_OPFLAG(OpSet) | NACL_OPFLAG(OpUse); | 25 const NaClOpFlags NaClOpSetOrUse = NACL_OPFLAG(OpSet) | NACL_OPFLAG(OpUse); |
| 24 | 26 |
| 25 Bool NaClIsBinaryUsingRegisters(const NaClInst* inst, | 27 Bool NaClIsBinaryUsingRegisters(const NaClInst* inst, |
| 26 NaClMnemonic name, | 28 NaClMnemonic name, |
| 27 NaClExpVector* vector, | 29 NaClExpVector* vector, |
| 28 NaClOpKind reg_1, | 30 NaClOpKind reg_1, |
| 29 NaClOpKind reg_2) { | 31 NaClOpKind reg_2) { |
| 30 return name == inst->name && | 32 return name == inst->name && |
| 31 2 == NaClGetInstNumberOperands(inst) && | 33 2 == NaClGetInstNumberOperandsInline(inst) && |
| 32 /* Note: Since the vector contains a list of operand expressions, the | 34 /* Note: Since the vector contains a list of operand expressions, the |
| 33 * first operand reference is always at index zero, and its first child | 35 * first operand reference is always at index zero, and its first child |
| 34 * (where the register would be defined) is at index 1. | 36 * (where the register would be defined) is at index 1. |
| 35 */ | 37 */ |
| 36 ExprRegister == vector->node[1].kind && | 38 ExprRegister == vector->node[1].kind && |
| 37 reg_1 == NaClGetExpRegister(&vector->node[1]) && | 39 reg_1 == NaClGetExpRegisterInline(&vector->node[1]) && |
| 38 /* Note: Since the first subtree is a register operand, it uses | 40 /* Note: Since the first subtree is a register operand, it uses |
| 39 * nodes 0 and 1 in the vector (node 0 is the operand reference, and | 41 * nodes 0 and 1 in the vector (node 0 is the operand reference, and |
| 40 * node 1 is its child defining a register value). The second operand | 42 * node 1 is its child defining a register value). The second operand |
| 41 * reference therefore lies at node 2, and if the operand is defined by | 43 * reference therefore lies at node 2, and if the operand is defined by |
| 42 * a register, it is the first kid of node 2, which is node 3. | 44 * a register, it is the first kid of node 2, which is node 3. |
| 43 */ | 45 */ |
| 44 ExprRegister == vector->node[3].kind && | 46 ExprRegister == vector->node[3].kind && |
| 45 reg_2 == NaClGetExpRegister(&vector->node[3]); | 47 reg_2 == NaClGetExpRegisterInline(&vector->node[3]); |
| 46 } | 48 } |
| 47 | 49 |
| 48 Bool NaClIsMovUsingRegisters(const NaClDecodeTables* tables, | 50 Bool NaClIsMovUsingRegisters(const NaClDecodeTables* tables, |
| 49 const NaClInst* inst, | 51 const NaClInst* inst, |
| 50 NaClExpVector* vector, | 52 NaClExpVector* vector, |
| 51 NaClOpKind reg_set, | 53 NaClOpKind reg_set, |
| 52 NaClOpKind reg_use) { | 54 NaClOpKind reg_use) { |
| 53 return NaClIsBinaryUsingRegisters(inst, InstMov, vector, reg_set, reg_use) && | 55 return NaClIsBinaryUsingRegisters(inst, InstMov, vector, reg_set, reg_use) && |
| 54 NACL_OPFLAG(OpSet) == | 56 NACL_OPFLAG(OpSet) == |
| 55 (NaClGetInstOperand(tables, inst, 0)->flags & NaClOpSetOrUse) && | 57 (NaClGetInstOperandInline(tables, inst, 0)->flags & NaClOpSetOrUse) && |
| 56 NACL_OPFLAG(OpUse) == | 58 NACL_OPFLAG(OpUse) == |
| 57 (NaClGetInstOperand(tables, inst, 1)->flags & NaClOpSetOrUse); | 59 (NaClGetInstOperandInline(tables, inst, 1)->flags & NaClOpSetOrUse); |
| 58 } | 60 } |
| 59 | 61 |
| 60 Bool NaClIsBinarySetUsingRegisters(const NaClDecodeTables* tables, | 62 Bool NaClIsBinarySetUsingRegisters(const NaClDecodeTables* tables, |
| 61 const NaClInst* inst, | 63 const NaClInst* inst, |
| 62 NaClMnemonic name, | 64 NaClMnemonic name, |
| 63 NaClExpVector* vector, | 65 NaClExpVector* vector, |
| 64 NaClOpKind reg_1, | 66 NaClOpKind reg_1, |
| 65 NaClOpKind reg_2) { | 67 NaClOpKind reg_2) { |
| 66 return NaClIsBinaryUsingRegisters(inst, name, vector, reg_1, reg_2) && | 68 return NaClIsBinaryUsingRegisters(inst, name, vector, reg_1, reg_2) && |
| 67 NaClOpSetOrUse == | 69 NaClOpSetOrUse == |
| 68 (NaClGetInstOperand(tables, inst, 0)->flags & NaClOpSetOrUse) && | 70 (NaClGetInstOperandInline(tables, inst, 0)->flags & NaClOpSetOrUse) && |
| 69 NACL_OPFLAG(OpUse) == | 71 NACL_OPFLAG(OpUse) == |
| 70 (NaClGetInstOperand(tables, inst, 1)->flags & NaClOpSetOrUse); | 72 (NaClGetInstOperandInline(tables, inst, 1)->flags & NaClOpSetOrUse); |
| 71 } | 73 } |
| 72 | 74 |
| 73 Bool NaClOperandOneIsRegisterSet(NaClInstState* inst, | 75 Bool NaClOperandOneIsRegisterSet(NaClInstState* inst, |
| 74 NaClOpKind reg_name) { | 76 NaClOpKind reg_name) { |
| 75 /* Note: Since the vector contains a list of operand expressions, the | 77 /* Note: Since the vector contains a list of operand expressions, the |
| 76 * first operand reference is always at index zero, and its first child | 78 * first operand reference is always at index zero, and its first child |
| 77 * (where the register would be defined) is at index 1. | 79 * (where the register would be defined) is at index 1. |
| 78 */ | 80 */ |
| 79 Bool result = FALSE; | 81 Bool result = FALSE; |
| 80 NaClExpVector* vector = NaClInstStateExpVector(inst); | 82 NaClExpVector* vector = NaClInstStateExpVector(inst); |
| 81 DEBUG(NaClLog(LOG_INFO, | 83 DEBUG(NaClLog(LOG_INFO, |
| 82 "->NaClOperandOneIsRegisterSet %s\n", | 84 "->NaClOperandOneIsRegisterSet %s\n", |
| 83 NaClOpKindName(reg_name))); | 85 NaClOpKindName(reg_name))); |
| 84 DEBUG(NaClExpVectorPrint(NaClLogGetGio(), vector)); | 86 DEBUG(NaClExpVectorPrint(NaClLogGetGio(), vector)); |
| 85 if (vector->number_expr_nodes >= 2) { | 87 if (vector->number_expr_nodes >= 2) { |
| 86 NaClExp* op_reg = &vector->node[1]; | 88 NaClExp* op_reg = &vector->node[1]; |
| 87 result = (ExprRegister == op_reg->kind && | 89 result = (ExprRegister == op_reg->kind && |
| 88 reg_name == NaClGetExpRegister(op_reg) && | 90 reg_name == NaClGetExpRegisterInline(op_reg) && |
| 89 (op_reg->flags & NACL_EFLAG(ExprSet))); | 91 (op_reg->flags & NACL_EFLAG(ExprSet))); |
| 90 } | 92 } |
| 91 DEBUG(NaClLog(LOG_INFO, | 93 DEBUG(NaClLog(LOG_INFO, |
| 92 "<-NaClOperandOneIsRegisterSet = %"NACL_PRIdBool"\n", result)); | 94 "<-NaClOperandOneIsRegisterSet = %"NACL_PRIdBool"\n", result)); |
| 93 return result; | 95 return result; |
| 94 } | 96 } |
| 95 | 97 |
| 96 Bool NaClOperandOneZeroExtends(NaClInstState* state) { | 98 Bool NaClOperandOneZeroExtends(NaClInstState* state) { |
| 97 Bool result = FALSE; | 99 Bool result = FALSE; |
| 98 const NaClInst* inst = NaClInstStateInst(state); | 100 const NaClInst* inst = NaClInstStateInst(state); |
| 99 DEBUG(NaClLog(LOG_INFO, "->NaClOperandOneZeroExtends\n")); | 101 DEBUG(NaClLog(LOG_INFO, "->NaClOperandOneZeroExtends\n")); |
| 100 DEBUG_OR_ERASE(NaClInstPrint(NaClLogGetGio(), state->decoder_tables, inst)); | 102 DEBUG_OR_ERASE(NaClInstPrint(NaClLogGetGio(), state->decoder_tables, inst)); |
| 101 result = (1 <= NaClGetInstNumberOperands(inst) && | 103 result = (1 <= NaClGetInstNumberOperandsInline(inst) && |
| 102 (NaClGetInstOperand(state->decoder_tables, inst, 0)->flags & | 104 (NaClGetInstOperandInline(state->decoder_tables, inst, 0)->flags & |
| 103 NACL_OPFLAG(OperandZeroExtends_v)) && | 105 NACL_OPFLAG(OperandZeroExtends_v)) && |
| 104 4 == NaClInstStateOperandSize(state)); | 106 4 == NaClInstStateOperandSize(state)); |
| 105 DEBUG(NaClLog(LOG_INFO, | 107 DEBUG(NaClLog(LOG_INFO, |
| 106 "<-NcOPerandOneZeroExtends = %"NACL_PRIdBool"\n", result)); | 108 "<-NcOPerandOneZeroExtends = %"NACL_PRIdBool"\n", result)); |
| 107 return result; | 109 return result; |
| 108 } | 110 } |
| 109 | 111 |
| 110 Bool NaClAssignsRegisterWithZeroExtends(NaClInstState* state, | 112 Bool NaClAssignsRegisterWithZeroExtends(NaClInstState* state, |
| 111 NaClOpKind reg_name) { | 113 NaClOpKind reg_name) { |
| 112 return NaClOperandOneIsRegisterSet(state, reg_name) && | 114 return NaClOperandOneIsRegisterSet(state, reg_name) && |
| 113 NaClOperandOneZeroExtends(state); | 115 NaClOperandOneZeroExtends(state); |
| 114 } | 116 } |
| OLD | NEW |