Commit 2174796b authored by Jacob.Bramley@arm.com's avatar Jacob.Bramley@arm.com

ARM64: Use templates for simulated memory accesses.

This cleans up the memory interface somewhat, and also avoids a memcpy
call that the compiler can't optimise away.

BUG=
R=bmeurer@chromium.org

Review URL: https://codereview.chromium.org/536923002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23640 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent c2fe5b2b
...@@ -1140,17 +1140,16 @@ void Simulator::PrintProcessorState() { ...@@ -1140,17 +1140,16 @@ void Simulator::PrintProcessorState() {
} }
void Simulator::PrintWrite(uint8_t* address, void Simulator::PrintWrite(uintptr_t address, uint64_t value,
uint64_t value,
unsigned num_bytes) { unsigned num_bytes) {
// The template is "# value -> address". The template is not directly used // The template is "# value -> address". The format string is not used
// in the printf since compilers tend to struggle with the parametrized // directly in the printf because some compilers struggle with the
// width (%0*). // parametrized width field (%0*).
const char* format = "# %s0x%0*" PRIx64 "%s -> %s0x%016" PRIx64 "%s\n"; const char* format = "# %s0x%0*" PRIx64 "%s -> %s0x%016" PRIxPTR "%s\n";
fprintf(stream_, fprintf(stream_,
format, format,
clr_memory_value, clr_memory_value,
num_bytes * 2, // The width in hexa characters. num_bytes * 2, // The width in hexadecimal characters.
value, value,
clr_normal, clr_normal,
clr_memory_address, clr_memory_address,
...@@ -1465,7 +1464,6 @@ void Simulator::LoadStoreHelper(Instruction* instr, ...@@ -1465,7 +1464,6 @@ void Simulator::LoadStoreHelper(Instruction* instr,
unsigned srcdst = instr->Rt(); unsigned srcdst = instr->Rt();
unsigned addr_reg = instr->Rn(); unsigned addr_reg = instr->Rn();
uint8_t* address = LoadStoreAddress(addr_reg, offset, addrmode); uint8_t* address = LoadStoreAddress(addr_reg, offset, addrmode);
int num_bytes = 1 << instr->SizeLS();
uint8_t* stack = NULL; uint8_t* stack = NULL;
// Handle the writeback for stores before the store. On a CPU the writeback // Handle the writeback for stores before the store. On a CPU the writeback
...@@ -1485,38 +1483,25 @@ void Simulator::LoadStoreHelper(Instruction* instr, ...@@ -1485,38 +1483,25 @@ void Simulator::LoadStoreHelper(Instruction* instr,
LoadStoreOp op = static_cast<LoadStoreOp>(instr->Mask(LoadStoreOpMask)); LoadStoreOp op = static_cast<LoadStoreOp>(instr->Mask(LoadStoreOpMask));
switch (op) { switch (op) {
case LDRB_w: case LDRB_w: set_wreg(srcdst, MemoryRead<uint8_t>(address)); break;
case LDRH_w: case LDRH_w: set_wreg(srcdst, MemoryRead<uint16_t>(address)); break;
case LDR_w: case LDR_w: set_wreg(srcdst, MemoryRead<uint32_t>(address)); break;
case LDR_x: set_xreg(srcdst, MemoryRead(address, num_bytes)); break; case LDR_x: set_xreg(srcdst, MemoryRead<uint64_t>(address)); break;
case STRB_w: case LDRSB_w: set_wreg(srcdst, MemoryRead<int8_t>(address)); break;
case STRH_w: case LDRSH_w: set_wreg(srcdst, MemoryRead<int16_t>(address)); break;
case STR_w: case LDRSB_x: set_xreg(srcdst, MemoryRead<int8_t>(address)); break;
case STR_x: MemoryWrite(address, xreg(srcdst), num_bytes); break; case LDRSH_x: set_xreg(srcdst, MemoryRead<int16_t>(address)); break;
case LDRSB_w: { case LDRSW_x: set_xreg(srcdst, MemoryRead<int32_t>(address)); break;
set_wreg(srcdst, ExtendValue<int32_t>(MemoryRead8(address), SXTB)); case LDR_s: set_sreg(srcdst, MemoryRead<float>(address)); break;
break; case LDR_d: set_dreg(srcdst, MemoryRead<double>(address)); break;
}
case LDRSB_x: { case STRB_w: MemoryWrite<uint8_t>(address, wreg(srcdst)); break;
set_xreg(srcdst, ExtendValue<int64_t>(MemoryRead8(address), SXTB)); case STRH_w: MemoryWrite<uint16_t>(address, wreg(srcdst)); break;
break; case STR_w: MemoryWrite<uint32_t>(address, wreg(srcdst)); break;
} case STR_x: MemoryWrite<uint64_t>(address, xreg(srcdst)); break;
case LDRSH_w: { case STR_s: MemoryWrite<float>(address, sreg(srcdst)); break;
set_wreg(srcdst, ExtendValue<int32_t>(MemoryRead16(address), SXTH)); case STR_d: MemoryWrite<double>(address, dreg(srcdst)); break;
break;
}
case LDRSH_x: {
set_xreg(srcdst, ExtendValue<int64_t>(MemoryRead16(address), SXTH));
break;
}
case LDRSW_x: {
set_xreg(srcdst, ExtendValue<int64_t>(MemoryRead32(address), SXTW));
break;
}
case LDR_s: set_sreg(srcdst, MemoryReadFP32(address)); break;
case LDR_d: set_dreg(srcdst, MemoryReadFP64(address)); break;
case STR_s: MemoryWriteFP32(address, sreg(srcdst)); break;
case STR_d: MemoryWriteFP64(address, dreg(srcdst)); break;
default: UNIMPLEMENTED(); default: UNIMPLEMENTED();
} }
...@@ -1590,49 +1575,48 @@ void Simulator::LoadStorePairHelper(Instruction* instr, ...@@ -1590,49 +1575,48 @@ void Simulator::LoadStorePairHelper(Instruction* instr,
switch (op) { switch (op) {
case LDP_w: { case LDP_w: {
set_wreg(rt, MemoryRead32(address)); set_wreg(rt, MemoryRead<uint32_t>(address));
set_wreg(rt2, MemoryRead32(address + kWRegSize)); set_wreg(rt2, MemoryRead<uint32_t>(address + kWRegSize));
break; break;
} }
case LDP_s: { case LDP_s: {
set_sreg(rt, MemoryReadFP32(address)); set_sreg(rt, MemoryRead<float>(address));
set_sreg(rt2, MemoryReadFP32(address + kSRegSize)); set_sreg(rt2, MemoryRead<float>(address + kSRegSize));
break; break;
} }
case LDP_x: { case LDP_x: {
set_xreg(rt, MemoryRead64(address)); set_xreg(rt, MemoryRead<uint64_t>(address));
set_xreg(rt2, MemoryRead64(address + kXRegSize)); set_xreg(rt2, MemoryRead<uint64_t>(address + kXRegSize));
break; break;
} }
case LDP_d: { case LDP_d: {
set_dreg(rt, MemoryReadFP64(address)); set_dreg(rt, MemoryRead<double>(address));
set_dreg(rt2, MemoryReadFP64(address + kDRegSize)); set_dreg(rt2, MemoryRead<double>(address + kDRegSize));
break; break;
} }
case LDPSW_x: { case LDPSW_x: {
set_xreg(rt, ExtendValue<int64_t>(MemoryRead32(address), SXTW)); set_xreg(rt, MemoryRead<int32_t>(address));
set_xreg(rt2, ExtendValue<int64_t>( set_xreg(rt2, MemoryRead<int32_t>(address + kWRegSize));
MemoryRead32(address + kWRegSize), SXTW));
break; break;
} }
case STP_w: { case STP_w: {
MemoryWrite32(address, wreg(rt)); MemoryWrite<uint32_t>(address, wreg(rt));
MemoryWrite32(address + kWRegSize, wreg(rt2)); MemoryWrite<uint32_t>(address + kWRegSize, wreg(rt2));
break; break;
} }
case STP_s: { case STP_s: {
MemoryWriteFP32(address, sreg(rt)); MemoryWrite<float>(address, sreg(rt));
MemoryWriteFP32(address + kSRegSize, sreg(rt2)); MemoryWrite<float>(address + kSRegSize, sreg(rt2));
break; break;
} }
case STP_x: { case STP_x: {
MemoryWrite64(address, xreg(rt)); MemoryWrite<uint64_t>(address, xreg(rt));
MemoryWrite64(address + kXRegSize, xreg(rt2)); MemoryWrite<uint64_t>(address + kXRegSize, xreg(rt2));
break; break;
} }
case STP_d: { case STP_d: {
MemoryWriteFP64(address, dreg(rt)); MemoryWrite<double>(address, dreg(rt));
MemoryWriteFP64(address + kDRegSize, dreg(rt2)); MemoryWrite<double>(address + kDRegSize, dreg(rt2));
break; break;
} }
default: UNREACHABLE(); default: UNREACHABLE();
...@@ -1661,10 +1645,10 @@ void Simulator::VisitLoadLiteral(Instruction* instr) { ...@@ -1661,10 +1645,10 @@ void Simulator::VisitLoadLiteral(Instruction* instr) {
unsigned rt = instr->Rt(); unsigned rt = instr->Rt();
switch (instr->Mask(LoadLiteralMask)) { switch (instr->Mask(LoadLiteralMask)) {
case LDR_w_lit: set_wreg(rt, MemoryRead32(address)); break; case LDR_w_lit: set_wreg(rt, MemoryRead<uint32_t>(address)); break;
case LDR_x_lit: set_xreg(rt, MemoryRead64(address)); break; case LDR_x_lit: set_xreg(rt, MemoryRead<uint64_t>(address)); break;
case LDR_s_lit: set_sreg(rt, MemoryReadFP32(address)); break; case LDR_s_lit: set_sreg(rt, MemoryRead<float>(address)); break;
case LDR_d_lit: set_dreg(rt, MemoryReadFP64(address)); break; case LDR_d_lit: set_dreg(rt, MemoryRead<double>(address)); break;
default: UNREACHABLE(); default: UNREACHABLE();
} }
} }
...@@ -1713,76 +1697,6 @@ void Simulator::CheckMemoryAccess(uint8_t* address, uint8_t* stack) { ...@@ -1713,76 +1697,6 @@ void Simulator::CheckMemoryAccess(uint8_t* address, uint8_t* stack) {
} }
uint64_t Simulator::MemoryRead(uint8_t* address, unsigned num_bytes) {
DCHECK(address != NULL);
DCHECK((num_bytes > 0) && (num_bytes <= sizeof(uint64_t)));
uint64_t read = 0;
memcpy(&read, address, num_bytes);
return read;
}
uint8_t Simulator::MemoryRead8(uint8_t* address) {
return MemoryRead(address, sizeof(uint8_t));
}
uint16_t Simulator::MemoryRead16(uint8_t* address) {
return MemoryRead(address, sizeof(uint16_t));
}
uint32_t Simulator::MemoryRead32(uint8_t* address) {
return MemoryRead(address, sizeof(uint32_t));
}
float Simulator::MemoryReadFP32(uint8_t* address) {
return rawbits_to_float(MemoryRead32(address));
}
uint64_t Simulator::MemoryRead64(uint8_t* address) {
return MemoryRead(address, sizeof(uint64_t));
}
double Simulator::MemoryReadFP64(uint8_t* address) {
return rawbits_to_double(MemoryRead64(address));
}
void Simulator::MemoryWrite(uint8_t* address,
uint64_t value,
unsigned num_bytes) {
DCHECK(address != NULL);
DCHECK((num_bytes > 0) && (num_bytes <= sizeof(uint64_t)));
LogWrite(address, value, num_bytes);
memcpy(address, &value, num_bytes);
}
void Simulator::MemoryWrite32(uint8_t* address, uint32_t value) {
MemoryWrite(address, value, sizeof(uint32_t));
}
void Simulator::MemoryWriteFP32(uint8_t* address, float value) {
MemoryWrite32(address, float_to_rawbits(value));
}
void Simulator::MemoryWrite64(uint8_t* address, uint64_t value) {
MemoryWrite(address, value, sizeof(uint64_t));
}
void Simulator::MemoryWriteFP64(uint8_t* address, double value) {
MemoryWrite64(address, double_to_rawbits(value));
}
void Simulator::VisitMoveWideImmediate(Instruction* instr) { void Simulator::VisitMoveWideImmediate(Instruction* instr) {
MoveWideImmediateOp mov_op = MoveWideImmediateOp mov_op =
static_cast<MoveWideImmediateOp>(instr->Mask(MoveWideImmediateMask)); static_cast<MoveWideImmediateOp>(instr->Mask(MoveWideImmediateMask));
......
...@@ -482,7 +482,7 @@ class Simulator : public DecoderVisitor { ...@@ -482,7 +482,7 @@ class Simulator : public DecoderVisitor {
void PrintRegisters(bool print_all_regs = false); void PrintRegisters(bool print_all_regs = false);
void PrintFPRegisters(bool print_all_regs = false); void PrintFPRegisters(bool print_all_regs = false);
void PrintProcessorState(); void PrintProcessorState();
void PrintWrite(uint8_t* address, uint64_t value, unsigned num_bytes); void PrintWrite(uintptr_t address, uint64_t value, unsigned num_bytes);
void LogSystemRegisters() { void LogSystemRegisters() {
if (log_parameters_ & LOG_SYS_REGS) PrintSystemRegisters(); if (log_parameters_ & LOG_SYS_REGS) PrintSystemRegisters();
} }
...@@ -497,8 +497,14 @@ class Simulator : public DecoderVisitor { ...@@ -497,8 +497,14 @@ class Simulator : public DecoderVisitor {
LogRegisters(); LogRegisters();
LogFPRegisters(); LogFPRegisters();
} }
void LogWrite(uint8_t* address, uint64_t value, unsigned num_bytes) { template <typename T>
if (log_parameters_ & LOG_WRITE) PrintWrite(address, value, num_bytes); void LogWrite(uintptr_t address, T value) {
uint64_t raw_value = 0;
DCHECK(sizeof(value) <= sizeof(raw_value));
if (log_parameters_ & LOG_WRITE) {
memcpy(&raw_value, &value, sizeof(value));
PrintWrite(address, raw_value, sizeof(value));
}
} }
int log_parameters() { return log_parameters_; } int log_parameters() { return log_parameters_; }
...@@ -597,20 +603,22 @@ class Simulator : public DecoderVisitor { ...@@ -597,20 +603,22 @@ class Simulator : public DecoderVisitor {
AddrMode addrmode); AddrMode addrmode);
void CheckMemoryAccess(uint8_t* address, uint8_t* stack); void CheckMemoryAccess(uint8_t* address, uint8_t* stack);
uint64_t MemoryRead(uint8_t* address, unsigned num_bytes); template <typename T, typename A>
uint8_t MemoryRead8(uint8_t* address); T MemoryRead(A address) {
uint16_t MemoryRead16(uint8_t* address); T value;
uint32_t MemoryRead32(uint8_t* address); STATIC_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) ||
float MemoryReadFP32(uint8_t* address); (sizeof(value) == 4) || (sizeof(value) == 8));
uint64_t MemoryRead64(uint8_t* address); memcpy(&value, reinterpret_cast<const void*>(address), sizeof(value));
double MemoryReadFP64(uint8_t* address); return value;
}
void MemoryWrite(uint8_t* address, uint64_t value, unsigned num_bytes);
void MemoryWrite32(uint8_t* address, uint32_t value);
void MemoryWriteFP32(uint8_t* address, float value);
void MemoryWrite64(uint8_t* address, uint64_t value);
void MemoryWriteFP64(uint8_t* address, double value);
template <typename T, typename A>
void MemoryWrite(A address, T value) {
STATIC_ASSERT((sizeof(value) == 1) || (sizeof(value) == 2) ||
(sizeof(value) == 4) || (sizeof(value) == 8));
LogWrite(reinterpret_cast<uintptr_t>(address), value);
memcpy(reinterpret_cast<void*>(address), &value, sizeof(value));
}
template <typename T> template <typename T>
T ShiftOperand(T value, T ShiftOperand(T value,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment