| Index: src/arm/simulator-arm.cc
|
| ===================================================================
|
| --- src/arm/simulator-arm.cc (revision 5347)
|
| +++ src/arm/simulator-arm.cc (working copy)
|
| @@ -2281,13 +2281,6 @@
|
| }
|
|
|
|
|
| -// Depending on value of last_bit flag glue register code from vm and m values
|
| -// (where m is expected to be a single bit).
|
| -static int GlueRegCode(bool last_bit, int vm, int m) {
|
| - return last_bit ? ((vm << 1) | m) : ((m << 4) | vm);
|
| -}
|
| -
|
| -
|
| // void Simulator::DecodeTypeVFP(Instr* instr)
|
| // The Following ARMv7 VFPv instructions are currently supported.
|
| // vmov :Sn = Rt
|
| @@ -2305,9 +2298,10 @@
|
| ASSERT((instr->TypeField() == 7) && (instr->Bit(24) == 0x0) );
|
| ASSERT(instr->Bits(11, 9) == 0x5);
|
|
|
| - int vm = instr->VmField();
|
| - int vd = instr->VdField();
|
| - int vn = instr->VnField();
|
| + // Obtain double precision register codes.
|
| + int vm = instr->VFPMRegCode(kDoublePrecision);
|
| + int vd = instr->VFPDRegCode(kDoublePrecision);
|
| + int vn = instr->VFPNRegCode(kDoublePrecision);
|
|
|
| if (instr->Bit(4) == 0) {
|
| if (instr->Opc1Field() == 0x7) {
|
| @@ -2315,9 +2309,13 @@
|
| if ((instr->Opc2Field() == 0x0) && (instr->Opc3Field() == 0x1)) {
|
| // vmov register to register.
|
| if (instr->SzField() == 0x1) {
|
| - set_d_register_from_double(vd, get_double_from_d_register(vm));
|
| + int m = instr->VFPMRegCode(kDoublePrecision);
|
| + int d = instr->VFPDRegCode(kDoublePrecision);
|
| + set_d_register_from_double(d, get_double_from_d_register(m));
|
| } else {
|
| - set_s_register_from_float(vd, get_float_from_s_register(vm));
|
| + int m = instr->VFPMRegCode(kSinglePrecision);
|
| + int d = instr->VFPDRegCode(kSinglePrecision);
|
| + set_s_register_from_float(d, get_float_from_s_register(m));
|
| }
|
| } else if ((instr->Opc2Field() == 0x7) && (instr->Opc3Field() == 0x3)) {
|
| DecodeVCVTBetweenDoubleAndSingle(instr);
|
| @@ -2410,7 +2408,7 @@
|
| (instr->VAField() == 0x0));
|
|
|
| int t = instr->RtField();
|
| - int n = GlueRegCode(true, instr->VnField(), instr->NField());
|
| + int n = instr->VFPNRegCode(kSinglePrecision);
|
| bool to_arm_register = (instr->VLField() == 0x1);
|
|
|
| if (to_arm_register) {
|
| @@ -2427,22 +2425,25 @@
|
| ASSERT((instr->Bit(4) == 0) && (instr->Opc1Field() == 0x7));
|
| ASSERT(((instr->Opc2Field() == 0x4) || (instr->Opc2Field() == 0x5)) &&
|
| (instr->Opc3Field() & 0x1));
|
| -
|
| // Comparison.
|
| - bool dp_operation = (instr->SzField() == 1);
|
|
|
| + VFPRegPrecision precision = kSinglePrecision;
|
| + if (instr->SzField() == 1) {
|
| + precision = kDoublePrecision;
|
| + }
|
| +
|
| if (instr->Bit(7) != 0) {
|
| // Raising exceptions for quiet NaNs are not supported.
|
| UNIMPLEMENTED(); // Not used by V8.
|
| }
|
|
|
| - int d = GlueRegCode(!dp_operation, instr->VdField(), instr->DField());
|
| + int d = instr->VFPDRegCode(precision);
|
| int m = 0;
|
| if (instr->Opc2Field() == 0x4) {
|
| - m = GlueRegCode(!dp_operation, instr->VmField(), instr->MField());
|
| + m = instr->VFPMRegCode(precision);
|
| }
|
|
|
| - if (dp_operation) {
|
| + if (precision == kDoublePrecision) {
|
| double dd_value = get_double_from_d_register(d);
|
| double dm_value = 0.0;
|
| if (instr->Opc2Field() == 0x4) {
|
| @@ -2460,11 +2461,17 @@
|
| ASSERT((instr->Bit(4) == 0) && (instr->Opc1Field() == 0x7));
|
| ASSERT((instr->Opc2Field() == 0x7) && (instr->Opc3Field() == 0x3));
|
|
|
| - bool double_to_single = (instr->SzField() == 1);
|
| - int dst = GlueRegCode(double_to_single, instr->VdField(), instr->DField());
|
| - int src = GlueRegCode(!double_to_single, instr->VmField(), instr->MField());
|
| + VFPRegPrecision dst_precision = kDoublePrecision;
|
| + VFPRegPrecision src_precision = kSinglePrecision;
|
| + if (instr->SzField() == 1) {
|
| + dst_precision = kSinglePrecision;
|
| + src_precision = kDoublePrecision;
|
| + }
|
|
|
| - if (double_to_single) {
|
| + int dst = instr->VFPDRegCode(dst_precision);
|
| + int src = instr->VFPMRegCode(src_precision);
|
| +
|
| + if (dst_precision == kSinglePrecision) {
|
| double val = get_double_from_d_register(src);
|
| set_s_register_from_float(dst, static_cast<float>(val));
|
| } else {
|
| @@ -2480,13 +2487,13 @@
|
| (((instr->Opc2Field() >> 1) == 0x6) && (instr->Opc3Field() & 0x1)));
|
|
|
| // Conversion between floating-point and integer.
|
| - int vd = instr->VdField();
|
| - int d = instr->DField();
|
| - int vm = instr->VmField();
|
| - int m = instr->MField();
|
| + bool to_integer = (instr->Bit(18) == 1);
|
|
|
| - bool to_integer = (instr->Bit(18) == 1);
|
| - bool dp_operation = (instr->SzField() == 1);
|
| + VFPRegPrecision src_precision = kSinglePrecision;
|
| + if (instr->SzField() == 1) {
|
| + src_precision = kDoublePrecision;
|
| + }
|
| +
|
| if (to_integer) {
|
| bool unsigned_integer = (instr->Bit(16) == 0);
|
| if (instr->Bit(7) != 1) {
|
| @@ -2494,10 +2501,10 @@
|
| UNIMPLEMENTED(); // Not used by V8.
|
| }
|
|
|
| - int dst = GlueRegCode(true, vd, d);
|
| - int src = GlueRegCode(!dp_operation, vm, m);
|
| + int dst = instr->VFPDRegCode(kSinglePrecision);
|
| + int src = instr->VFPMRegCode(src_precision);
|
|
|
| - if (dp_operation) {
|
| + if (src_precision == kDoublePrecision) {
|
| double val = get_double_from_d_register(src);
|
|
|
| int sint = unsigned_integer ? static_cast<uint32_t>(val) :
|
| @@ -2515,12 +2522,12 @@
|
| } else {
|
| bool unsigned_integer = (instr->Bit(7) == 0);
|
|
|
| - int dst = GlueRegCode(!dp_operation, vd, d);
|
| - int src = GlueRegCode(true, vm, m);
|
| + int dst = instr->VFPDRegCode(src_precision);
|
| + int src = instr->VFPMRegCode(kSinglePrecision);
|
|
|
| int val = get_sinteger_from_s_register(src);
|
|
|
| - if (dp_operation) {
|
| + if (src_precision == kDoublePrecision) {
|
| if (unsigned_integer) {
|
| set_d_register_from_double(dst,
|
| static_cast<double>((uint32_t)val));
|
| @@ -2551,9 +2558,11 @@
|
| if (instr->CoprocessorField() == 0xA) {
|
| switch (instr->OpcodeField()) {
|
| case 0x8:
|
| - case 0xC: { // Load and store float to memory.
|
| + case 0xA:
|
| + case 0xC:
|
| + case 0xE: { // Load and store single precision float to memory.
|
| int rn = instr->RnField();
|
| - int vd = instr->VdField();
|
| + int vd = instr->VFPDRegCode(kSinglePrecision);
|
| int offset = instr->Immed8Field();
|
| if (!instr->HasU()) {
|
| offset = -offset;
|
|
|