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

Unified Diff: src/arm64/simulator-arm64.cc

Issue 213943002: Change arm64 simulator register backing store. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 7 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
« src/arm64/simulator-arm64.h ('K') | « src/arm64/simulator-arm64.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm64/simulator-arm64.cc
diff --git a/src/arm64/simulator-arm64.cc b/src/arm64/simulator-arm64.cc
index c7c9f6cedd9105aef766f45f273dfcf8226d9fc1..3d7cf97dd15d398bd350d4ed0548133200f7dd34 100644
--- a/src/arm64/simulator-arm64.cc
+++ b/src/arm64/simulator-arm64.cc
@@ -878,32 +878,38 @@ int64_t Simulator::AddWithCarry(unsigned reg_size,
}
-int64_t Simulator::ShiftOperand(unsigned reg_size,
- int64_t value,
- Shift shift_type,
- unsigned amount) {
+template<> struct make_unsigned<int32_t> {
+ public:
+ typedef uint32_t type;
+};
+
+
+template<> struct make_unsigned<int64_t> {
+ public:
jbramley 2014/05/16 14:05:50 Is 'public' necessary here?
Fritz 2014/05/16 18:11:46 Yes. Below it is accessed make_unsigned<T>::type
Sven Panne 2014/05/19 08:12:26 Huh? struct = class + public, so this shouldn't be
Fritz 2014/05/20 19:44:24 Your correct. My mistake. Done.
+ typedef uint64_t type;
+};
+
+
+template <typename T>
+T Simulator::ShiftOperand(T value, Shift shift_type, unsigned amount) {
+ typedef typename make_unsigned<T>::type unsignedT;
jbramley 2014/05/16 14:05:50 I don't like this mechanism I'm afraid; it's not a
Fritz 2014/05/16 18:11:46 I haven't found away around this yet. Propagating
+
if (amount == 0) {
return value;
}
- int64_t mask = reg_size == kXRegSizeInBits ? kXRegMask : kWRegMask;
+
switch (shift_type) {
case LSL:
- return (value << amount) & mask;
+ return value << amount;
case LSR:
- return static_cast<uint64_t>(value) >> amount;
+ return static_cast<unsignedT>(value) >> amount;
case ASR: {
- // Shift used to restore the sign.
- unsigned s_shift = kXRegSizeInBits - reg_size;
- // Value with its sign restored.
- int64_t s_value = (value << s_shift) >> s_shift;
- return (s_value >> amount) & mask;
+ return value >> amount;
}
case ROR: {
- if (reg_size == kWRegSizeInBits) {
- value &= kWRegMask;
- }
- return (static_cast<uint64_t>(value) >> amount) |
- ((value & ((1L << amount) - 1L)) << (reg_size - amount));
+ return (static_cast<unsignedT>(value) >> amount) |
+ ((value & ((1L << amount) - 1L)) <<
+ (sizeof(unsignedT) * 8 - amount));
}
default:
UNIMPLEMENTED();
@@ -1289,12 +1295,17 @@ void Simulator::AddSubHelper(Instruction* instr, int64_t op2) {
void Simulator::VisitAddSubShifted(Instruction* instr) {
- unsigned reg_size = instr->SixtyFourBits() ? kXRegSizeInBits
- : kWRegSizeInBits;
- int64_t op2 = ShiftOperand(reg_size,
- reg(reg_size, instr->Rm()),
- static_cast<Shift>(instr->ShiftDP()),
- instr->ImmDPShift());
+ int64_t op2 = 0;
+ if (instr->SixtyFourBits()) {
+ op2 = ShiftOperand(xreg(instr->Rm()),
+ static_cast<Shift>(instr->ShiftDP()),
+ instr->ImmDPShift());
+ } else {
+ op2 = ShiftOperand(wreg(instr->Rm()),
+ static_cast<Shift>(instr->ShiftDP()),
+ instr->ImmDPShift());
jbramley 2014/05/16 14:05:50 This would be clearer (and fit on one line) if it
Fritz 2014/05/16 18:11:46 Done.
+ op2 &= kWRegMask;
+ }
AddSubHelper(instr, op2);
}
@@ -1337,12 +1348,17 @@ void Simulator::VisitAddSubWithCarry(Instruction* instr) {
void Simulator::VisitLogicalShifted(Instruction* instr) {
- unsigned reg_size = instr->SixtyFourBits() ? kXRegSizeInBits
- : kWRegSizeInBits;
Shift shift_type = static_cast<Shift>(instr->ShiftDP());
unsigned shift_amount = instr->ImmDPShift();
- int64_t op2 = ShiftOperand(reg_size, reg(reg_size, instr->Rm()), shift_type,
- shift_amount);
+ int64_t op2 = 0;
+
+ if (instr->SixtyFourBits()) {
+ op2 = ShiftOperand(xreg(instr->Rm()), shift_type, shift_amount);
+ } else {
+ op2 = ShiftOperand(wreg(instr->Rm()), shift_type, shift_amount);
+ op2 &= kWRegMask;
jbramley 2014/05/16 14:05:50 Doesn't the new ShiftOperand apply that mask? If s
Fritz 2014/05/16 18:11:46 ShiftOperand was returning a signed int64_t. It's
+ }
+
if (instr->Mask(NOT) == NOT) {
op2 = ~op2;
}
@@ -1910,29 +1926,19 @@ uint64_t Simulator::ReverseBytes(uint64_t value, ReverseByteMode mode) {
return result;
}
-
-void Simulator::VisitDataProcessing2Source(Instruction* instr) {
+template <typename T>
+void Simulator::DataProcessing2Source(Instruction* instr) {
+ typedef typename make_unsigned<T>::type unsignedT;
Shift shift_op = NO_SHIFT;
- int64_t result = 0;
+ T result = 0;
+ const T kMinimumInteger = static_cast<T>(1) << (sizeof(T) * 8 - 1);
jbramley 2014/05/16 14:05:50 Consider adding a helper function to do this (perh
Fritz 2014/05/16 18:11:46 Thanks, great idea.
Sven Panne 2014/05/19 08:12:26 Even better idea: Use <limits>: http://www.cpluspl
Fritz 2014/05/20 19:44:24 Done.
switch (instr->Mask(DataProcessing2SourceMask)) {
- case SDIV_w: {
- int32_t rn = wreg(instr->Rn());
- int32_t rm = wreg(instr->Rm());
- if ((rn == kWMinInt) && (rm == -1)) {
- result = kWMinInt;
- } else if (rm == 0) {
- // Division by zero can be trapped, but not on A-class processors.
- result = 0;
- } else {
- result = rn / rm;
- }
- break;
- }
+ case SDIV_w:
case SDIV_x: {
- int64_t rn = xreg(instr->Rn());
- int64_t rm = xreg(instr->Rm());
- if ((rn == kXMinInt) && (rm == -1)) {
- result = kXMinInt;
+ T rn = reg<T>(instr->Rn());
+ T rm = reg<T>(instr->Rm());
+ if ((rn == kMinimumInteger) && (rm == -1)) {
+ result = kMinimumInteger;
} else if (rm == 0) {
// Division by zero can be trapped, but not on A-class processors.
result = 0;
@@ -1941,20 +1947,10 @@ void Simulator::VisitDataProcessing2Source(Instruction* instr) {
}
break;
}
- case UDIV_w: {
- uint32_t rn = static_cast<uint32_t>(wreg(instr->Rn()));
- uint32_t rm = static_cast<uint32_t>(wreg(instr->Rm()));
- if (rm == 0) {
- // Division by zero can be trapped, but not on A-class processors.
- result = 0;
- } else {
- result = rn / rm;
- }
- break;
- }
+ case UDIV_w:
case UDIV_x: {
- uint64_t rn = static_cast<uint64_t>(xreg(instr->Rn()));
- uint64_t rm = static_cast<uint64_t>(xreg(instr->Rm()));
+ unsignedT rn = static_cast<unsignedT>(reg<T>(instr->Rn()));
+ unsignedT rm = static_cast<unsignedT>(reg<T>(instr->Rm()));
if (rm == 0) {
// Division by zero can be trapped, but not on A-class processors.
result = 0;
@@ -1974,18 +1970,27 @@ void Simulator::VisitDataProcessing2Source(Instruction* instr) {
default: UNIMPLEMENTED();
}
- unsigned reg_size = instr->SixtyFourBits() ? kXRegSizeInBits
- : kWRegSizeInBits;
if (shift_op != NO_SHIFT) {
// Shift distance encoded in the least-significant five/six bits of the
// register.
- int mask = (instr->SixtyFourBits() == 1) ? kShiftAmountXRegMask
- : kShiftAmountWRegMask;
- unsigned shift = wreg(instr->Rm()) & mask;
- result = ShiftOperand(reg_size, reg(reg_size, instr->Rn()), shift_op,
- shift);
+ unsigned shift = wreg(instr->Rm());
+ if (sizeof(T) == kWRegSize) {
+ shift &= kShiftAmountWRegMask;
+ } else {
+ shift &= kShiftAmountXRegMask;
+ }
+ result = ShiftOperand(reg<T>(instr->Rn()), shift_op, shift);
+ }
+ set_reg<T>(instr->Rd(), result);
+}
+
+
+void Simulator::VisitDataProcessing2Source(Instruction* instr) {
+ if (instr->SixtyFourBits()) {
+ DataProcessing2Source<int64_t>(instr);
+ } else {
+ DataProcessing2Source<int32_t>(instr);
}
- set_reg(reg_size, instr->Rd(), result);
}
« src/arm64/simulator-arm64.h ('K') | « src/arm64/simulator-arm64.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698