| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2012 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 #include "native_client/src/trusted/validator_arm/baseline_classes.h" | 7 #include "native_client/src/trusted/validator_arm/baseline_classes.h" |
| 8 | 8 |
| 9 #include <assert.h> | 9 #include <assert.h> |
| 10 #include <string.h> | 10 #include <string.h> |
| 11 | 11 |
| 12 // Implementations of instruction classes, for those not completely defined in | 12 // Implementations of instruction classes, for those not completely defined in |
| 13 // in the header. | 13 // in the header. |
| 14 | 14 |
| 15 namespace nacl_arm_dec { | 15 namespace nacl_arm_dec { |
| 16 | 16 |
| 17 // Unary1RegisterImmediateOp | 17 // Unary1RegisterImmediateOp |
| 18 SafetyLevel Unary1RegisterImmediateOp::safety(const Instruction i) const { | 18 SafetyLevel Unary1RegisterImmediateOp::safety(const Instruction i) const { |
| 19 if (d.reg(i) == kRegisterPc) return UNPREDICTABLE; | 19 if (d.reg(i) == kRegisterPc) return UNPREDICTABLE; |
| 20 | 20 |
| 21 // Note: We would restrict out PC as well for Rd in NaCl, but no need | 21 // Note: We would restrict out PC as well for Rd in NaCl, but no need |
| 22 // since the ARM restriction doesn't allow it anyway. | 22 // since the ARM restriction doesn't allow it anyway. |
| 23 return MAY_BE_SAFE; | 23 return MAY_BE_SAFE; |
| 24 } | 24 } |
| 25 | 25 |
| 26 RegisterList Unary1RegisterImmediateOp::defs(const Instruction i) const { | 26 RegisterList Unary1RegisterImmediateOp::defs(const Instruction i) const { |
| 27 return d.reg(i) + flags.reg_if_updated(i); | 27 return d.reg(i) + conditions.conds_if_updated(i); |
| 28 } | 28 } |
| 29 | 29 |
| 30 // Binary2RegisterImmediateOp | 30 // Binary2RegisterImmediateOp |
| 31 SafetyLevel Binary2RegisterImmediateOp::safety(Instruction i) const { | 31 SafetyLevel Binary2RegisterImmediateOp::safety(Instruction i) const { |
| 32 // NaCl Constraint. | 32 // NaCl Constraint. |
| 33 if (d.reg(i) == kRegisterPc) return FORBIDDEN_OPERANDS; | 33 if (d.reg(i) == kRegisterPc) return FORBIDDEN_OPERANDS; |
| 34 return MAY_BE_SAFE; | 34 return MAY_BE_SAFE; |
| 35 } | 35 } |
| 36 | 36 |
| 37 RegisterList Binary2RegisterImmediateOp::defs(Instruction i) const { | 37 RegisterList Binary2RegisterImmediateOp::defs(Instruction i) const { |
| 38 return d.reg(i) + flags.reg_if_updated(i); | 38 return d.reg(i) + conditions.conds_if_updated(i); |
| 39 } | 39 } |
| 40 | 40 |
| 41 // TODO(karl): find out why we added this so that we allowed an | 41 // TODO(karl): find out why we added this so that we allowed an |
| 42 // override on NaCl restriction that one can write to r15. | 42 // override on NaCl restriction that one can write to r15. |
| 43 // MaskedBinary2RegisterImmediateOp | 43 // MaskedBinary2RegisterImmediateOp |
| 44 // SafetyLevel MaskedBinary2RegisterImmediateOp::safety(Instruction i) const { | 44 // SafetyLevel MaskedBinary2RegisterImmediateOp::safety(Instruction i) const { |
| 45 // UNREFERENCED_PARAMETER(i); | 45 // UNREFERENCED_PARAMETER(i); |
| 46 // return MAY_BE_SAFE; | 46 // return MAY_BE_SAFE; |
| 47 // } | 47 // } |
| 48 | 48 |
| 49 bool MaskedBinary2RegisterImmediateOp::clears_bits( | 49 bool MaskedBinary2RegisterImmediateOp::clears_bits( |
| 50 Instruction i, uint32_t mask) const { | 50 Instruction i, uint32_t mask) const { |
| 51 return (imm.get_modified_immediate(i) & mask) == mask; | 51 return (imm.get_modified_immediate(i) & mask) == mask; |
| 52 } | 52 } |
| 53 | 53 |
| 54 // BinaryRegisterImmediateTest:: | 54 // BinaryRegisterImmediateTest:: |
| 55 SafetyLevel BinaryRegisterImmediateTest::safety(Instruction i) const { | 55 SafetyLevel BinaryRegisterImmediateTest::safety(Instruction i) const { |
| 56 UNREFERENCED_PARAMETER(i); | 56 UNREFERENCED_PARAMETER(i); |
| 57 return MAY_BE_SAFE; | 57 return MAY_BE_SAFE; |
| 58 } | 58 } |
| 59 | 59 |
| 60 RegisterList BinaryRegisterImmediateTest::defs(Instruction i) const { | 60 RegisterList BinaryRegisterImmediateTest::defs(Instruction i) const { |
| 61 return flags.reg_if_updated(i); | 61 return conditions.conds_if_updated(i); |
| 62 } | 62 } |
| 63 | 63 |
| 64 // MaskedBinaryRegisterImmediateTest | 64 // MaskedBinaryRegisterImmediateTest |
| 65 bool MaskedBinaryRegisterImmediateTest::sets_Z_if_bits_clear( | 65 bool MaskedBinaryRegisterImmediateTest::sets_Z_if_bits_clear( |
| 66 Instruction i, Register r, uint32_t mask) const { | 66 Instruction i, Register r, uint32_t mask) const { |
| 67 return n.reg(i) == r && | 67 return n.reg(i) == r && |
| 68 (imm.get_modified_immediate(i) & mask) == mask && | 68 (imm.get_modified_immediate(i) & mask) == mask && |
| 69 defs(i)[kRegisterFlags]; | 69 defs(i)[kConditions]; |
| 70 } | 70 } |
| 71 | 71 |
| 72 // Unary2RegisterOp | 72 // Unary2RegisterOp |
| 73 SafetyLevel Unary2RegisterOp::safety(const Instruction i) const { | 73 SafetyLevel Unary2RegisterOp::safety(const Instruction i) const { |
| 74 // NaCl Constraint. | 74 // NaCl Constraint. |
| 75 if (d.reg(i) == kRegisterPc) return FORBIDDEN_OPERANDS; | 75 if (d.reg(i) == kRegisterPc) return FORBIDDEN_OPERANDS; |
| 76 return MAY_BE_SAFE; | 76 return MAY_BE_SAFE; |
| 77 } | 77 } |
| 78 | 78 |
| 79 RegisterList Unary2RegisterOp::defs(const Instruction i) const { | 79 RegisterList Unary2RegisterOp::defs(const Instruction i) const { |
| 80 return d.reg(i) + flags.reg_if_updated(i); | 80 return d.reg(i) + conditions.conds_if_updated(i); |
| 81 } | 81 } |
| 82 | 82 |
| 83 // Binary3RegisterOp | 83 // Binary3RegisterOp |
| 84 SafetyLevel Binary3RegisterOp::safety(const Instruction i) const { | 84 SafetyLevel Binary3RegisterOp::safety(const Instruction i) const { |
| 85 // Unsafe if any register contains PC (ARM restriction). | 85 // Unsafe if any register contains PC (ARM restriction). |
| 86 if ((d.reg(i) + m.reg(i) + n.reg(i))[kRegisterPc]) return UNPREDICTABLE; | 86 if ((d.reg(i) + m.reg(i) + n.reg(i))[kRegisterPc]) return UNPREDICTABLE; |
| 87 | 87 |
| 88 | 88 |
| 89 // Note: We would restrict out PC as well for Rd in NaCl, but no need | 89 // Note: We would restrict out PC as well for Rd in NaCl, but no need |
| 90 // since the ARM restriction doesn't allow it anyway. | 90 // since the ARM restriction doesn't allow it anyway. |
| 91 return MAY_BE_SAFE; | 91 return MAY_BE_SAFE; |
| 92 } | 92 } |
| 93 | 93 |
| 94 RegisterList Binary3RegisterOp::defs(const Instruction i) const { | 94 RegisterList Binary3RegisterOp::defs(const Instruction i) const { |
| 95 return d.reg(i) + flags.reg_if_updated(i); | 95 return d.reg(i) + conditions.conds_if_updated(i); |
| 96 } | 96 } |
| 97 | 97 |
| 98 // Unary2RegisterImmedShiftedOp | 98 // Unary2RegisterImmedShiftedOp |
| 99 SafetyLevel Unary2RegisterImmedShiftedOp::safety(const Instruction i) const { | 99 SafetyLevel Unary2RegisterImmedShiftedOp::safety(const Instruction i) const { |
| 100 // NaCl Constraint. | 100 // NaCl Constraint. |
| 101 if (d.reg(i) == kRegisterPc) return FORBIDDEN_OPERANDS; | 101 if (d.reg(i) == kRegisterPc) return FORBIDDEN_OPERANDS; |
| 102 return MAY_BE_SAFE; | 102 return MAY_BE_SAFE; |
| 103 } | 103 } |
| 104 | 104 |
| 105 RegisterList Unary2RegisterImmedShiftedOp::defs(const Instruction i) const { | 105 RegisterList Unary2RegisterImmedShiftedOp::defs(const Instruction i) const { |
| 106 return d.reg(i) + flags.reg_if_updated(i); | 106 return d.reg(i) + conditions.conds_if_updated(i); |
| 107 } | 107 } |
| 108 | 108 |
| 109 // Unary3RegisterShiftedOp | 109 // Unary3RegisterShiftedOp |
| 110 SafetyLevel Unary3RegisterShiftedOp::safety(Instruction i) const { | 110 SafetyLevel Unary3RegisterShiftedOp::safety(Instruction i) const { |
| 111 // Unsafe if any register contains PC (ARM restriction). | 111 // Unsafe if any register contains PC (ARM restriction). |
| 112 if ((d.reg(i) + s.reg(i) + m.reg(i))[kRegisterPc]) return UNPREDICTABLE; | 112 if ((d.reg(i) + s.reg(i) + m.reg(i))[kRegisterPc]) return UNPREDICTABLE; |
| 113 | 113 |
| 114 // Note: We would restrict out PC as well for Rd in NaCl, but no need | 114 // Note: We would restrict out PC as well for Rd in NaCl, but no need |
| 115 // since the ARM restriction doesn't allow it anyway. | 115 // since the ARM restriction doesn't allow it anyway. |
| 116 return MAY_BE_SAFE; | 116 return MAY_BE_SAFE; |
| 117 } | 117 } |
| 118 | 118 |
| 119 RegisterList Unary3RegisterShiftedOp::defs(const Instruction i) const { | 119 RegisterList Unary3RegisterShiftedOp::defs(const Instruction i) const { |
| 120 return d.reg(i) + flags.reg_if_updated(i); | 120 return d.reg(i) + conditions.conds_if_updated(i); |
| 121 } | 121 } |
| 122 | 122 |
| 123 // Binary3RegisterImmedShiftedOp | 123 // Binary3RegisterImmedShiftedOp |
| 124 SafetyLevel Binary3RegisterImmedShiftedOp::safety(const Instruction i) const { | 124 SafetyLevel Binary3RegisterImmedShiftedOp::safety(const Instruction i) const { |
| 125 // NaCl Constraint. | 125 // NaCl Constraint. |
| 126 if (d.reg(i) == kRegisterPc) return FORBIDDEN_OPERANDS; | 126 if (d.reg(i) == kRegisterPc) return FORBIDDEN_OPERANDS; |
| 127 return MAY_BE_SAFE; | 127 return MAY_BE_SAFE; |
| 128 } | 128 } |
| 129 | 129 |
| 130 RegisterList Binary3RegisterImmedShiftedOp::defs(const Instruction i) const { | 130 RegisterList Binary3RegisterImmedShiftedOp::defs(const Instruction i) const { |
| 131 return d.reg(i) + flags.reg_if_updated(i); | 131 return d.reg(i) + conditions.conds_if_updated(i); |
| 132 } | 132 } |
| 133 | 133 |
| 134 // Binary4RegisterShiftedOp | 134 // Binary4RegisterShiftedOp |
| 135 SafetyLevel Binary4RegisterShiftedOp::safety(Instruction i) const { | 135 SafetyLevel Binary4RegisterShiftedOp::safety(Instruction i) const { |
| 136 // Unsafe if any register contains PC (ARM restriction). | 136 // Unsafe if any register contains PC (ARM restriction). |
| 137 if ((d.reg(i) + n.reg(i) + s.reg(i) + m.reg(i))[kRegisterPc]) | 137 if ((d.reg(i) + n.reg(i) + s.reg(i) + m.reg(i))[kRegisterPc]) |
| 138 return UNPREDICTABLE; | 138 return UNPREDICTABLE; |
| 139 | 139 |
| 140 // Note: We would restrict out PC as well for Rd in NaCl, but no need | 140 // Note: We would restrict out PC as well for Rd in NaCl, but no need |
| 141 // since the ARM restriction doesn't allow it anyway. | 141 // since the ARM restriction doesn't allow it anyway. |
| 142 return MAY_BE_SAFE; | 142 return MAY_BE_SAFE; |
| 143 } | 143 } |
| 144 | 144 |
| 145 RegisterList Binary4RegisterShiftedOp::defs(const Instruction i) const { | 145 RegisterList Binary4RegisterShiftedOp::defs(const Instruction i) const { |
| 146 return d.reg(i) + flags.reg_if_updated(i); | 146 return d.reg(i) + conditions.conds_if_updated(i); |
| 147 } | 147 } |
| 148 | 148 |
| 149 // Binary2RegisterImmedShiftedTest | 149 // Binary2RegisterImmedShiftedTest |
| 150 SafetyLevel Binary2RegisterImmedShiftedTest::safety(const Instruction i) const { | 150 SafetyLevel Binary2RegisterImmedShiftedTest::safety(const Instruction i) const { |
| 151 UNREFERENCED_PARAMETER(i); | 151 UNREFERENCED_PARAMETER(i); |
| 152 return MAY_BE_SAFE; | 152 return MAY_BE_SAFE; |
| 153 } | 153 } |
| 154 | 154 |
| 155 RegisterList Binary2RegisterImmedShiftedTest::defs(const Instruction i) const { | 155 RegisterList Binary2RegisterImmedShiftedTest::defs(const Instruction i) const { |
| 156 return flags.reg_if_updated(i); | 156 return conditions.conds_if_updated(i); |
| 157 } | 157 } |
| 158 | 158 |
| 159 // Binary3RegisterShiftedTest | 159 // Binary3RegisterShiftedTest |
| 160 SafetyLevel Binary3RegisterShiftedTest::safety(Instruction i) const { | 160 SafetyLevel Binary3RegisterShiftedTest::safety(Instruction i) const { |
| 161 // Unsafe if any register contains PC (ARM restriction). | 161 // Unsafe if any register contains PC (ARM restriction). |
| 162 if ((n.reg(i) + s.reg(i) + m.reg(i))[kRegisterPc]) return UNPREDICTABLE; | 162 if ((n.reg(i) + s.reg(i) + m.reg(i))[kRegisterPc]) return UNPREDICTABLE; |
| 163 return MAY_BE_SAFE; | 163 return MAY_BE_SAFE; |
| 164 } | 164 } |
| 165 | 165 |
| 166 RegisterList Binary3RegisterShiftedTest::defs(const Instruction i) const { | 166 RegisterList Binary3RegisterShiftedTest::defs(const Instruction i) const { |
| 167 return flags.reg_if_updated(i); | 167 return conditions.conds_if_updated(i); |
| 168 } | 168 } |
| 169 | 169 |
| 170 } // namespace | 170 } // namespace |
| OLD | NEW |