mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-23 00:24:11 -08:00
classlib: implement Integer.compareUnsigned in Wasm and C
This commit is contained in:
parent
a3f0ec52d4
commit
a7f115a541
|
@ -27,6 +27,7 @@ public class IntegerIntrinsic implements Intrinsic {
|
||||||
switch (method.getName()) {
|
switch (method.getName()) {
|
||||||
case "divideUnsigned":
|
case "divideUnsigned":
|
||||||
case "remainderUnsigned":
|
case "remainderUnsigned":
|
||||||
|
case "compareUnsigned":
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
@ -42,6 +43,13 @@ public class IntegerIntrinsic implements Intrinsic {
|
||||||
case "remainderUnsigned":
|
case "remainderUnsigned":
|
||||||
writeBinary(context, invocation, "%");
|
writeBinary(context, invocation, "%");
|
||||||
break;
|
break;
|
||||||
|
case "compareUnsigned":
|
||||||
|
context.writer().print("teavm_compare_u32(");
|
||||||
|
context.emit(invocation.getArguments().get(0));
|
||||||
|
context.writer().print(", ");
|
||||||
|
context.emit(invocation.getArguments().get(1));
|
||||||
|
context.writer().print(")");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,10 @@ public final class WasmRuntime {
|
||||||
return gt(a, b) ? 1 : lt(a, b) ? -1 : 0;
|
return gt(a, b) ? 1 : lt(a, b) ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int compareUnsigned(int a, int b) {
|
||||||
|
return gtu(a, b) ? 1 : ltu(a, b) ? -1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
public static int compare(long a, long b) {
|
public static int compare(long a, long b) {
|
||||||
return gt(a, b) ? 1 : lt(a, b) ? -1 : 0;
|
return gt(a, b) ? 1 : lt(a, b) ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
@ -55,6 +59,10 @@ public final class WasmRuntime {
|
||||||
|
|
||||||
private static native boolean gt(int a, int b);
|
private static native boolean gt(int a, int b);
|
||||||
|
|
||||||
|
private static native boolean ltu(int a, int b);
|
||||||
|
|
||||||
|
private static native boolean gtu(int a, int b);
|
||||||
|
|
||||||
private static native boolean lt(long a, long b);
|
private static native boolean lt(long a, long b);
|
||||||
|
|
||||||
private static native boolean gt(long a, long b);
|
private static native boolean gt(long a, long b);
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
package org.teavm.backend.wasm.intrinsics;
|
package org.teavm.backend.wasm.intrinsics;
|
||||||
|
|
||||||
import org.teavm.ast.InvocationExpr;
|
import org.teavm.ast.InvocationExpr;
|
||||||
|
import org.teavm.backend.wasm.WasmRuntime;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmCall;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmIntBinary;
|
import org.teavm.backend.wasm.model.expression.WasmIntBinary;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmIntBinaryOperation;
|
import org.teavm.backend.wasm.model.expression.WasmIntBinaryOperation;
|
||||||
|
@ -23,6 +25,9 @@ import org.teavm.backend.wasm.model.expression.WasmIntType;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
|
|
||||||
public class IntegerIntrinsic implements WasmIntrinsic {
|
public class IntegerIntrinsic implements WasmIntrinsic {
|
||||||
|
private static final MethodReference COMPARE_UNSIGNED = new MethodReference(WasmRuntime.class,
|
||||||
|
"compareUnsigned", int.class, int.class, int.class);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isApplicable(MethodReference methodReference) {
|
public boolean isApplicable(MethodReference methodReference) {
|
||||||
if (!methodReference.getClassName().equals(Integer.class.getName())) {
|
if (!methodReference.getClassName().equals(Integer.class.getName())) {
|
||||||
|
@ -32,6 +37,7 @@ public class IntegerIntrinsic implements WasmIntrinsic {
|
||||||
switch (methodReference.getName()) {
|
switch (methodReference.getName()) {
|
||||||
case "divideUnsigned":
|
case "divideUnsigned":
|
||||||
case "remainderUnsigned":
|
case "remainderUnsigned":
|
||||||
|
case "compareUnsigned":
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
@ -49,6 +55,10 @@ public class IntegerIntrinsic implements WasmIntrinsic {
|
||||||
return new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.REM_UNSIGNED,
|
return new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.REM_UNSIGNED,
|
||||||
manager.generate(invocation.getArguments().get(0)),
|
manager.generate(invocation.getArguments().get(0)),
|
||||||
manager.generate(invocation.getArguments().get(1)));
|
manager.generate(invocation.getArguments().get(1)));
|
||||||
|
case "compareUnsigned":
|
||||||
|
return new WasmCall(manager.getNames().forMethod(COMPARE_UNSIGNED),
|
||||||
|
manager.generate(invocation.getArguments().get(0)),
|
||||||
|
manager.generate(invocation.getArguments().get(1)));
|
||||||
default:
|
default:
|
||||||
throw new AssertionError();
|
throw new AssertionError();
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,8 @@ public class WasmRuntimeIntrinsic implements WasmIntrinsic {
|
||||||
switch (methodReference.getName()) {
|
switch (methodReference.getName()) {
|
||||||
case "gt":
|
case "gt":
|
||||||
case "lt":
|
case "lt":
|
||||||
|
case "gtu":
|
||||||
|
case "ltu":
|
||||||
case "initStack":
|
case "initStack":
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
|
@ -53,6 +55,12 @@ public class WasmRuntimeIntrinsic implements WasmIntrinsic {
|
||||||
case "gt":
|
case "gt":
|
||||||
return comparison(WasmIntBinaryOperation.GT_SIGNED, WasmFloatBinaryOperation.GT,
|
return comparison(WasmIntBinaryOperation.GT_SIGNED, WasmFloatBinaryOperation.GT,
|
||||||
invocation, manager);
|
invocation, manager);
|
||||||
|
case "ltu":
|
||||||
|
return comparison(WasmIntBinaryOperation.LT_UNSIGNED, WasmFloatBinaryOperation.LT,
|
||||||
|
invocation, manager);
|
||||||
|
case "gtu":
|
||||||
|
return comparison(WasmIntBinaryOperation.GT_UNSIGNED, WasmFloatBinaryOperation.GT,
|
||||||
|
invocation, manager);
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException(invocation.getMethod().getName());
|
throw new IllegalArgumentException(invocation.getMethod().getName());
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,6 +129,9 @@ extern void teavm_throwArrayIndexOutOfBoundsException();
|
||||||
static inline int32_t teavm_compare_i32(int32_t a, int32_t b) {
|
static inline int32_t teavm_compare_i32(int32_t a, int32_t b) {
|
||||||
return a > b ? INT32_C(1) : a < b ? INT32_C(-1) : INT32_C(0);
|
return a > b ? INT32_C(1) : a < b ? INT32_C(-1) : INT32_C(0);
|
||||||
}
|
}
|
||||||
|
static inline int32_t teavm_compare_u32(int32_t a, int32_t b) {
|
||||||
|
return (uint32_t) a > (uint32_t) b ? INT32_C(1) : (uint32_t) a < (uint32_t) b ? INT32_C(-1) : INT32_C(0);
|
||||||
|
}
|
||||||
static inline int32_t teavm_compare_i64(int64_t a, int64_t b) {
|
static inline int32_t teavm_compare_i64(int64_t a, int64_t b) {
|
||||||
return a > b ? INT32_C(1) : a < b ? INT32_C(-1) : INT32_C(0);
|
return a > b ? INT32_C(1) : a < b ? INT32_C(-1) : INT32_C(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ TeaVM.wasm = function() {
|
||||||
let length = instance.exports.teavm_arrayLength(arrayPtr);
|
let length = instance.exports.teavm_arrayLength(arrayPtr);
|
||||||
let arrayData = new DataView(memory, instance.exports.teavm_charArrayData(arrayPtr), length * 2);
|
let arrayData = new DataView(memory, instance.exports.teavm_charArrayData(arrayPtr), length * 2);
|
||||||
for (let i = 0; i < length; ++i) {
|
for (let i = 0; i < length; ++i) {
|
||||||
putwchar(arrayData.memory.getUint16(i * 2, true));
|
putwchar(arrayData.getUint16(i * 2, true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function logInt(i) {
|
function logInt(i) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user