diff --git a/js/src/jit-test/tests/basic/loongarch-minimal-jit.js b/js/src/jit-test/tests/basic/loongarch-minimal-jit.js index e24997d73d..71e3ff9ca0 100644 --- a/js/src/jit-test/tests/basic/loongarch-minimal-jit.js +++ b/js/src/jit-test/tests/basic/loongarch-minimal-jit.js @@ -48,6 +48,14 @@ function boolStrictEq(a, b) { return (a < b) === (b > a); } +function strictBoolIntEq(a, b) { + return (a < b) === 1; +} + +function strictBoolIntNe(a, b) { + return (a < b) !== 1; +} + function boolLooseEq(a, b) { return (a < b) == 1; } @@ -104,6 +112,18 @@ function remainderNegativeZero(a) { return a % 2; } +function uint16Const() { + return 50000; +} + +function uint24Const() { + return 70000; +} + +function popMany(a, b) { + return (a + 1, b + 2, a + 3, b + 4, a + b); +} + function assignArg(a, b) { a = a < b; return a; @@ -159,6 +179,10 @@ assertEq(notLess(2, 3), false); assertEq(notLess(3, 2), true); assertEq(boolStrictEq(2, 3), true); assertEq(boolStrictEq(3, 2), true); +assertEq(strictBoolIntEq(2, 3), false); +assertEq(strictBoolIntEq(3, 2), false); +assertEq(strictBoolIntNe(2, 3), true); +assertEq(strictBoolIntNe(3, 2), true); assertEq(boolLooseEq(2, 3), true); assertEq(boolLooseEq(3, 2), false); assertEq(boolLooseNe(2, 3), false); @@ -187,6 +211,9 @@ assertEq(divide(-2147483648, -1), 2147483648); assertEq(remainder(7, 3), 1); assertEq(remainder(8, 2), 0); assertEq(1 / remainderNegativeZero(-4), -Infinity); +assertEq(uint16Const(), 50000); +assertEq(uint24Const(), 70000); +assertEq(popMany(3, 4), 7); assertEq(assignArg(2, 3), true); assertEq(assignArg(3, 2), false); assertEq(boolToNumeric(2, 3), 1); diff --git a/js/src/jit/LoongArchMinimalJit.cpp b/js/src/jit/LoongArchMinimalJit.cpp index e253639344..ff8d1ef904 100644 --- a/js/src/jit/LoongArchMinimalJit.cpp +++ b/js/src/jit/LoongArchMinimalJit.cpp @@ -504,6 +504,42 @@ class MinimalLoongArchCompiler return pushTempFromReg(top.reg, top.kind); } + bool duplicateTopTwo() { + if (stackDepth_ < 2) + return false; + StackValue lhs = stack_[stackDepth_ - 2]; + StackValue rhs = stack_[stackDepth_ - 1]; + return pushTempFromReg(lhs.reg, lhs.kind) && + pushTempFromReg(rhs.reg, rhs.kind); + } + + bool duplicateAt(uint32_t index) { + if (index >= stackDepth_) + return false; + const StackValue& value = stack_[stackDepth_ - index - 1]; + return pushTempFromReg(value.reg, value.kind); + } + + bool pick(uint32_t index) { + if (index >= stackDepth_) + return false; + StackValue value = stack_[stackDepth_ - index - 1]; + for (size_t i = stackDepth_ - index - 1; i + 1 < stackDepth_; i++) + stack_[i] = stack_[i + 1]; + stack_[stackDepth_ - 1] = value; + return true; + } + + bool unpick(uint32_t index) { + if (index >= stackDepth_) + return false; + StackValue value = stack_[stackDepth_ - 1]; + for (size_t i = stackDepth_ - 1; i > stackDepth_ - index - 1; i--) + stack_[i] = stack_[i - 1]; + stack_[stackDepth_ - index - 1] = value; + return true; + } + bool pop(StackValue* value) { if (!stackDepth_) return false; @@ -659,6 +695,14 @@ class MinimalLoongArchCompiler if (!pushTempFromImm(GET_INT8(pc), MinimalValueKind::Int32)) return false; break; + case JSOP_UINT16: + if (!pushTempFromImm(GET_UINT16(pc), MinimalValueKind::Int32)) + return false; + break; + case JSOP_UINT24: + if (!pushTempFromImm(GET_UINT24(pc), MinimalValueKind::Int32)) + return false; + break; case JSOP_INT32: if (!pushTempFromImm(GET_INT32(pc), MinimalValueKind::Int32)) return false; @@ -668,10 +712,23 @@ class MinimalLoongArchCompiler return false; stackDepth_--; break; + case JSOP_POPN: + if (GET_UINT16(pc) > stackDepth_) + return false; + stackDepth_ -= GET_UINT16(pc); + break; case JSOP_DUP: if (!duplicateTop()) return false; break; + case JSOP_DUP2: + if (!duplicateTopTwo()) + return false; + break; + case JSOP_DUPAT: + if (!duplicateAt(GET_UINT24(pc))) + return false; + break; case JSOP_SWAP: { if (stackDepth_ < 2) return false; @@ -680,6 +737,14 @@ class MinimalLoongArchCompiler stack_[stackDepth_ - 2] = tmp; break; } + case JSOP_PICK: + if (!pick(GET_UINT8(pc))) + return false; + break; + case JSOP_UNPICK: + if (!unpick(GET_UINT8(pc))) + return false; + break; case JSOP_TONUMERIC: case JSOP_POS: if (!stackDepth_ || !IsNumericKind(stack_[stackDepth_ - 1].kind)) @@ -767,8 +832,12 @@ class MinimalLoongArchCompiler bool invert = op == JSOP_NE || op == JSOP_STRICTNE; bool strict = op == JSOP_STRICTEQ || op == JSOP_STRICTNE; if (IsNumericKind(lhs.kind) && IsNumericKind(rhs.kind)) { - if (!emitEq(lhs.reg, rhs.reg, out, invert)) + if (strict && lhs.kind != rhs.kind) { + if (!emitLoadImm32(out, invert ? 1 : 0)) + return false; + } else if (!emitEq(lhs.reg, rhs.reg, out, invert)) { return false; + } } else { bool equal = false; if (strict) {