Index: src/arm/simulator-arm.cc |
diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc |
index 6c22a0a86acdf51736324dae3e2f943b35e39d35..730aa8883b52686de9b6e2a0519cf1ca2197c647 100644 |
--- a/src/arm/simulator-arm.cc |
+++ b/src/arm/simulator-arm.cc |
@@ -4028,6 +4028,45 @@ void Simulator::DecodeSpecialCondition(Instruction* instr) { |
UNIMPLEMENTED(); |
} |
break; |
+ case 0x1C: |
+ if ((instr->Bits(11, 9) == 0x5) && (instr->Bit(6) == 0) && |
+ (instr->Bit(4) == 0)) { |
+ // VSEL* (floating-point) |
+ bool condition_holds; |
+ switch (instr->Bits(21, 20)) { |
+ case 0x0: // VSELEQ |
+ condition_holds = (z_flag_ == 1); |
+ break; |
+ case 0x1: // VSELVS |
+ condition_holds = (v_flag_ == 1); |
+ break; |
+ case 0x2: // VSELGE |
+ condition_holds = (n_flag_ == v_flag_); |
+ break; |
+ case 0x3: // VSELGT |
+ condition_holds = ((z_flag_ == 0) && (n_flag_ == v_flag_)); |
+ break; |
+ default: |
+ UNREACHABLE(); // Case analysis is exhaustive. |
+ break; |
+ } |
+ if (instr->SzValue() == 0x1) { |
+ int n = instr->VFPNRegValue(kDoublePrecision); |
+ int m = instr->VFPMRegValue(kDoublePrecision); |
+ int d = instr->VFPDRegValue(kDoublePrecision); |
+ double result = get_double_from_d_register(condition_holds ? n : m); |
+ set_d_register_from_double(d, result); |
+ } else { |
+ int n = instr->VFPNRegValue(kSinglePrecision); |
+ int m = instr->VFPMRegValue(kSinglePrecision); |
+ int d = instr->VFPDRegValue(kSinglePrecision); |
+ float result = get_float_from_s_register(condition_holds ? n : m); |
+ set_s_register_from_float(d, result); |
+ } |
+ } else { |
+ UNIMPLEMENTED(); |
+ } |
+ break; |
default: |
UNIMPLEMENTED(); |
break; |