Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(22)

Unified Diff: src/trusted/validator_arm/inst_classes.cc

Issue 7799013: Intial Thumb2 Sandbox (naclrev 6680) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: fix comma Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/trusted/validator_arm/inst_classes.cc
diff --git a/src/trusted/validator_arm/inst_classes.cc b/src/trusted/validator_arm/inst_classes.cc
index 9b7a9bac7692a0445e363f82d5b42382b6cee436..fa87798ebd3bf940371b53708f167b9bc2be5ac1 100644
--- a/src/trusted/validator_arm/inst_classes.cc
+++ b/src/trusted/validator_arm/inst_classes.cc
@@ -5,7 +5,8 @@
*/
#include "native_client/src/trusted/validator_arm/inst_classes.h"
-
+// TODO(mrm) remove when debug is gone
bsy 2011/09/21 22:32:17 mrm
jasonwkim 2011/09/26 21:35:52 all mrm fixed
+#include <stdio.h>
/*
* Implementations of instruction classes, for those not completely defined in
* the header.
@@ -419,4 +420,274 @@ int32_t Branch::branch_target_offset(const Instruction i) const {
return offset + 8; // because r15 reads as 8 bytes ahead
}
+/* Thumb Functions */
Karl 2011/09/19 19:56:05 Thumb2?
jasonwkim 2011/09/26 21:35:52 Thumb is more correct in this case
+SafetyLevel Def3::safety(Instruction i) const {
+ /* If it tries to write to PC, unsafe */
+ if (defs(i)[kRegisterPc]) {
+ return FORBIDDEN_OPERANDS;
+ }
+ return MAY_BE_SAFE;
+}
+
+RegisterList Def3::defs(Instruction i) const {
+ return i.reg(3, 0);
+}
+
+SafetyLevel Def8_10::safety(Instruction i) const {
+ // TODO(mrm) should be encoding impossible, check
+ if (defs(i)[kRegisterPc]) {
+ return FORBIDDEN_OPERANDS;
+ }
+ return MAY_BE_SAFE;
+}
+
+RegisterList Def8_10::defs(Instruction i) const {
+ return i.reg(10, 8);
+}
+
+SafetyLevel MemOpThumb::safety(Instruction i) const {
+ // Don't let addressing writeback alter PC.
+ // TODO(mrm): Check if this is possible, we may be able to remove this.
+ if (defs(i)[kRegisterPc]) return FORBIDDEN_OPERANDS;
+
+ return MAY_BE_SAFE;
+}
+
+Register MemOpThumb::base_address_register(Instruction i) const {
+ return i.reg(5, 3);
+}
+
+RegisterList MemOpThumbLoad::defs(Instruction i) const {
+ return i.reg(2, 0);
+}
+
+// TODO(mrm) double check, this is suspect
+// Specifically, double check if I need to +4 things?
+int32_t CmpBrZ::branch_target_offset(Instruction i) const {
+ return int32_t ((i.bits(9, 9) << 6) & (i.bits(7, 3) << 1));
+}
+
+RegisterList PopMult::defs(Instruction i) const {
+ return RegisterList(i.bits(7, 0)) + kRegisterStack;
+}
+
+SafetyLevel BranchTCond::safety(Instruction i) const {
+ if ((condition(i) & 14) != 14)
+ return MAY_BE_SAFE;
+ return FORBIDDEN_OPERANDS;
+}
+
+// TODO(mrm) Check if I need to +4
+int32_t BranchT1::branch_target_offset(Instruction i) const {
+ // Sign extend and left shift by one
+ return ((int32_t)(i.bits(7, 0) << 24)) >> 23;
+}
+
+// TODO(mrm) write test
+Instruction::Condition BranchT1::condition(Instruction i) const {
+ return (Instruction::Condition)i.bits(11, 8);
+}
+
+// TODO(mrm) Check if I need to +4
+int32_t BranchT2::branch_target_offset(Instruction i) const {
+ // Sign extend and left shift by one.
+ return ((int32_t)(i.bits(10, 0) << 21)) >> 20;
+}
+
+// TODO(mrm) Check if I need to +4
+int32_t BranchT3::branch_target_offset(Instruction i) const {
+ // Construct the value
+ uint32_t val = ((((((((i.bit(10) << 1) | i.bit(27)) << 1) | i.bit(29)) << 6)
+ | i.bits(5, 0)) << 11) | i.bits(26, 16)) << 1;
+ // Sign extend it.
+ return ((int32_t)(val << 9)) >> 9;
+}
+
+Instruction::Condition BranchT3::condition(Instruction i) const {
+ return (Instruction::Condition)i.bits(9, 6);
+}
+
+int32_t get_stretched_immediate(Instruction i) {
+ uint32_t s = i.bit(10);
+ uint32_t i1 = (~(i.bit(27) ^ s)) & 1;
+ uint32_t i2 = (~(i.bit(29) ^ s)) & 1;
+ // Construct the value
+ uint32_t val = ((((((((i.bit(10) << 1) | i1) << 1) | i2) << 10)
+ | i.bits(9, 0)) << 11) | i.bits(26, 16)) << 1;
+ // Sign extend it, adjust for pc shift
+ return (((int32_t)(val << 9)) >> 9);
+}
+
+int32_t BranchT4::branch_target_offset(Instruction i) const {
+ return get_stretched_immediate(i) + 4;
+}
+
+// TODO(mrm) LDMT1/STMT1 could be cleaned up
+RegisterList LDMT1::defs(Instruction i) const {
+ return RegisterList(i.bits(7, 0));
+}
+
+RegisterList STMT1::defs(Instruction i) const {
+ return RegisterList(i.bits(7, 0)) + i.reg(10, 8);
+}
+
+RegisterList STMT1::immediate_addressing_defs(Instruction i) const {
+ return i.reg(10, 8);
+}
+
+Register STMT1::base_address_register(Instruction i) const {
+ return i.reg(10, 8);
+}
+
+RegisterList LDRLitT1::defs(Instruction i) const {
+ return i.reg(10, 8);
+}
+
+RegisterList ADRT1::defs(Instruction i) const {
+ return i.reg(10, 8);
+}
+
+RegisterList MemOpSPThumbLoad::defs(Instruction i) const {
+ return i.reg(10, 8);
+}
+
+RegisterList DPMImm::defs(Instruction i) const {
+ return i.reg(27, 24);
+}
+
+uint32_t get_thumb_modified_immediate(Instruction i) {
+ uint32_t raw = i.bits(23, 16);
+ uint8_t shift_mode = (((i.bits(10, 10) << 3) | i.bits(30, 28)) << 1)
+ | i.bits(23, 23);
+ switch (shift_mode >> 1) {
+ case 0: return raw;
+ case 1: return (raw << 16) | raw;
+ case 2: return ((raw << 16) | raw) << 8;
+ case 3: return (((((raw << 8) | raw) << 8) | raw) << 8) | raw;
+ default: return (raw | (1 << 7)) << (31 - 7 - (shift_mode - 8));
+ };
+}
+
+bool BicModImmT::clears_bits(Instruction i, uint32_t mask) const {
+ return (get_thumb_modified_immediate(i) & mask) == mask;
+}
+
+bool OrrModImmT::sets_bits(Instruction i, uint32_t mask) const {
+ return get_thumb_modified_immediate(i) == mask;
+}
+
+RegisterList MovT::defs(Instruction i) const {
+ return Register((i.bits(7, 7) << 3) | i.bits(2, 0));
+}
+
+Register BXT::branch_target_register(Instruction i) const {
+ return i.reg(6, 3);
+}
+
+int32_t BLT::branch_target_offset(Instruction i) const {
+ return get_stretched_immediate(i);
+}
+
+ITCond IT::it_sequence(Instruction i) const {
+ uint8_t firstmask = i.bit(4);
+ ITCond base = it_set(0, THEN, 0);
+ uint8_t maskdex = 0;
+ while (i.bit(maskdex) == 0)
+ maskdex++;
+ // TODO(mrm) Add a guard to the parse table to make sure the mask is never 0
+ maskdex++;
+ for (uint8_t conddex = 1; maskdex < 4; maskdex++, conddex++) {
+ base = it_set(conddex, i.bit(maskdex) == firstmask ? THEN : ELSE, base);
+ }
+ return base;
+}
+
+Instruction::Condition IT::condition(Instruction i) const {
+ return (Instruction::Condition)i.bits(7, 4);
+}
+
+RegisterList STMTD::defs(Instruction i) const {
+ return i.reg(3, 0);
+}
+
+Register STMTD::base_address_register(Instruction i) const {
+ return i.reg(3, 0);
+}
+
+RegisterList STMTD::immediate_addressing_defs(Instruction i) const {
+ return base_address_register(i);
+}
+
+RegisterList LDMTD::defs(Instruction i) const {
+ return i.reg(3, 0) + RegisterList(i.bits(12, 0));
+}
+
+Register StrS::base_address_register(Instruction i) const {
+ return i.reg(3, 0);
+}
+
+// Note that while this doesn't always write something to i.reg(3, 0), it is
+// safe to pretend that it does.
+RegisterList StrS::defs(Instruction i) const {
+ return i.reg(3, 0);
+}
+
+Register LDRImmT3::base_address_register(Instruction i) const {
+ return i.reg(3, 0);
+}
+
+RegisterList LDRImmT4::defs(Instruction i) const {
+ if (i.bit(8 + 16)) {
+ return base_address_register(i); // Writeback
+ } else {
+ return kRegisterNone;
+ }
+}
+
+RegisterList LDRImmT4::immediate_addressing_defs(Instruction i) const {
+ return defs(i);
+}
+
+RegisterList Def31_18::defs(Instruction i) const {
+ return i.reg(31, 18);
+}
+
+RegisterList StrEx::defs(Instruction i) const {
+ return immediate_addressing_defs(i) + i.reg(11 + 16, 8 + 16);
+}
+
+RegisterList StrEx::immediate_addressing_defs(Instruction i) const {
+ if (i.bit(5))
+ return base_address_register(i);
+ return kRegisterNone;
+}
+
+Register StrEx::base_address_register(Instruction i) const {
+ return i.reg(3, 0);
+}
+
+RegisterList LdrEx::defs(Instruction i) const {
+ return immediate_addressing_defs(i) + i.reg(15 + 16, 12 + 16);
+}
+
+RegisterList StrD::defs(Instruction i) const {
+ return immediate_addressing_defs(i);
+}
+
+RegisterList LdrD::defs(Instruction i) const {
+ return immediate_addressing_defs(i) + i.reg(11 + 16, 8 + 16)
+ + i.reg(15 + 16, 12 + 16);
+}
+
+RegisterList Def27_24::defs(Instruction i) const {
+ return i.reg(27, 24);
+}
+
+bool ThumbBreakpoint::is_literal_pool_head(Instruction i) const {
+ UNREFERENCED_PARAMETER(i);
+ return true; //TODO We ideally want to think about conditions, but due to the
+ //rule that IT cannot straddle a boundary, and this has to start
+ //a bundle, we're fine.
+}
+
} // namespace

Powered by Google App Engine
This is Rietveld 408576698