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

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

Issue 173567: ARM native regexps. (Closed)
Patch Set: Created 11 years, 4 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/arm/simulator-arm.cc
diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc
index d12ddbfaa71f04c02d2c243a8dc90e71283a0987..f870edd33b65859ddc0f672ddd899402b56eaf5d 100644
--- a/src/arm/simulator-arm.cc
+++ b/src/arm/simulator-arm.cc
@@ -26,7 +26,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <stdlib.h>
-
+#include <cstdarg>
#include "v8.h"
#include "disasm.h"
@@ -1416,8 +1416,12 @@ void Simulator::DecodeType01(Instr* instr) {
case CMN: {
if (instr->HasS()) {
- Format(instr, "cmn'cond 'rn, 'shift_rm");
- Format(instr, "cmn'cond 'rn, 'imm");
+ // Format(instr, "cmn'cond 'rn, 'shift_rm");
+ // Format(instr, "cmn'cond 'rn, 'imm");
+ alu_out = rn_val + shifter_operand;
+ SetNZFlags(alu_out);
+ SetCFlag(!CarryFrom(rn_val, shifter_operand));
+ SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, true));
} else {
ASSERT(type == 0);
int rm = instr->RmField();
@@ -1566,6 +1570,7 @@ void Simulator::DecodeType2(Instr* instr) {
void Simulator::DecodeType3(Instr* instr) {
+ ASSERT(instr->Bit(4) == 0);
int rd = instr->RdField();
int rn = instr->RnField();
int32_t rn_val = get_register(rn);
@@ -1605,7 +1610,12 @@ void Simulator::DecodeType3(Instr* instr) {
}
}
if (instr->HasB()) {
- UNIMPLEMENTED();
+ if (instr->HasL()) {
+ uint8_t byte = ReadB(addr);
+ set_register(rd, byte);
+ } else {
+ UNIMPLEMENTED();
+ }
} else {
if (instr->HasL()) {
set_register(rd, ReadW(addr, instr));
@@ -1654,14 +1664,75 @@ void Simulator::DecodeType7(Instr* instr) {
}
+void Simulator::DecodeUnconditional(Instr* instr) {
+ if (instr->Bits(7, 4) == 0x0B && instr->Bits(27, 25) == 0 && instr->HasL()) {
+ // Load halfword instruction, either register or immediate offset.
+ int rd = instr->RdField();
+ int rn = instr->RnField();
+ int32_t rn_val = get_register(rn);
+ int32_t addr = 0;
+ int32_t offset;
+ if (instr->Bit(22) == 0) {
+ // Register offset.
+ int rm = instr->RmField();
+ offset = get_register(rm);
+ } else {
+ // Immediate offset
+ offset = instr->Bits(3, 0) + (instr->Bits(11, 8) << 4);
+ }
+ switch (instr->PUField()) {
+ case 0: {
+ // Post index, negative.
+ ASSERT(!instr->HasW());
+ addr = rn_val;
+ rn_val -= offset;
+ set_register(rn, rn_val);
+ break;
+ }
+ case 1: {
+ // Post index, positive.
+ ASSERT(!instr->HasW());
+ addr = rn_val;
+ rn_val += offset;
+ set_register(rn, rn_val);
+ break;
+ }
+ case 2: {
+ // Pre index or offset, negative.
+ rn_val -= offset;
+ addr = rn_val;
+ if (instr->HasW()) {
+ set_register(rn, rn_val);
+ }
+ break;
+ }
+ case 3: {
+ // Pre index or offset, positive.
+ rn_val += offset;
+ addr = rn_val;
+ if (instr->HasW()) {
+ set_register(rn, rn_val);
+ }
+ break;
+ }
+ default: {
+ // The PU field is a 2-bit field.
+ UNREACHABLE();
+ break;
+ }
+ }
+ // Not sign extending, so load as unsigned.
+ uint16_t halfword = ReadH(addr, instr);
+ set_register(rd, halfword);
+ } else {
+ UNIMPLEMENTED();
+ }
+}
+
+
// Executes the current instruction.
void Simulator::InstructionDecode(Instr* instr) {
pc_modified_ = false;
- if (instr->ConditionField() == special_condition) {
- Debugger dbg(this);
- dbg.Stop(instr);
- return;
- }
if (::v8::internal::FLAG_trace_sim) {
disasm::NameConverter converter;
disasm::Disassembler dasm(converter);
@@ -1671,7 +1742,9 @@ void Simulator::InstructionDecode(Instr* instr) {
reinterpret_cast<byte*>(instr));
PrintF(" 0x%x %s\n", instr, buffer.start());
}
- if (ConditionallyExecute(instr)) {
+ if (instr->ConditionField() == special_condition) {
+ DecodeUnconditional(instr);
+ } else if (ConditionallyExecute(instr)) {
switch (instr->TypeField()) {
case 0:
case 1: {
@@ -1747,19 +1820,35 @@ void Simulator::Execute() {
}
-Object* Simulator::Call(int32_t entry, int32_t p0, int32_t p1, int32_t p2,
- int32_t p3, int32_t p4) {
- // Setup parameters
- set_register(r0, p0);
- set_register(r1, p1);
- set_register(r2, p2);
- set_register(r3, p3);
- intptr_t* stack_pointer = reinterpret_cast<intptr_t*>(get_register(sp));
- *(--stack_pointer) = p4;
- set_register(sp, reinterpret_cast<int32_t>(stack_pointer));
+int32_t Simulator::Call(byte* entry, int argument_count, ...) {
+ va_list parameters;
+ va_start(parameters, argument_count);
+ // Setup arguments
+
+ // First four arguments passed in registers.
+ ASSERT(argument_count >= 4);
+ set_register(r0, va_arg(parameters, int32_t));
+ set_register(r1, va_arg(parameters, int32_t));
+ set_register(r2, va_arg(parameters, int32_t));
+ set_register(r3, va_arg(parameters, int32_t));
+
+ // Remaining arguments passed on stack.
+ int original_stack = get_register(sp);
+ // Compute position of stack on entry to generated code.
+ int entry_stack = (original_stack - (argument_count - 4) * sizeof(int32_t));
+ if (OS::ActivationFrameAlignment() != 0) {
+ entry_stack &= -OS::ActivationFrameAlignment();
+ }
+ // Store remaining arguments on stack, from low to high memory.
+ intptr_t* stack_argument = reinterpret_cast<intptr_t*>(entry_stack);
+ for (int i = 4; i < argument_count; i++) {
+ stack_argument[i - 4] = va_arg(parameters, int32_t);
+ }
+ va_end(parameters);
+ set_register(sp, entry_stack);
// Prepare to execute the code at entry
- set_register(pc, entry);
+ set_register(pc, reinterpret_cast<int32_t>(entry));
// Put down marker for end of simulation. The simulator will stop simulation
// when the PC reaches this value. By saving the "end simulation" value into
// the LR the simulation stops when returning to this call point.
@@ -1793,14 +1882,14 @@ Object* Simulator::Call(int32_t entry, int32_t p0, int32_t p1, int32_t p2,
Execute();
// Check that the callee-saved registers have been preserved.
- CHECK_EQ(get_register(r4), callee_saved_value);
- CHECK_EQ(get_register(r5), callee_saved_value);
- CHECK_EQ(get_register(r6), callee_saved_value);
- CHECK_EQ(get_register(r7), callee_saved_value);
- CHECK_EQ(get_register(r8), callee_saved_value);
- CHECK_EQ(get_register(r9), callee_saved_value);
- CHECK_EQ(get_register(r10), callee_saved_value);
- CHECK_EQ(get_register(r11), callee_saved_value);
+ CHECK_EQ(callee_saved_value, get_register(r4));
+ CHECK_EQ(callee_saved_value, get_register(r5));
+ CHECK_EQ(callee_saved_value, get_register(r6));
+ CHECK_EQ(callee_saved_value, get_register(r7));
+ CHECK_EQ(callee_saved_value, get_register(r8));
+ CHECK_EQ(callee_saved_value, get_register(r9));
+ CHECK_EQ(callee_saved_value, get_register(r10));
+ CHECK_EQ(callee_saved_value, get_register(r11));
// Restore callee-saved registers with the original value.
set_register(r4, r4_val);
@@ -1812,8 +1901,12 @@ Object* Simulator::Call(int32_t entry, int32_t p0, int32_t p1, int32_t p2,
set_register(r10, r10_val);
set_register(r11, r11_val);
- int result = get_register(r0);
- return reinterpret_cast<Object*>(result);
+ // Pop stack passed arguments.
+ CHECK_EQ(entry_stack, get_register(sp));
+ set_register(sp, original_stack);
+
+ int32_t result = get_register(r0);
+ return result;
}
} } // namespace assembler::arm

Powered by Google App Engine
This is Rietveld 408576698