Source code

Revision control

Copy as Markdown

Other Tools

// |jit-test| test-also=--wasm-compiler=optimizing --disable-wasm-huge-memory; skip-if: !hasDisassembler() || wasmCompileMode() != "ion" || !getBuildConfiguration("loong64"); include:codegen-loong64-test.js
// Test that loads/stores at constant offsets yield expected code.
//
// WASM HeapReg is "$s7".
// Friendly si12 offsets.
codegenTestLOONG64_adhoc(
`(module
(memory 1)
(func (export "f") (result i32)
(i32.load (i32.const 1000))))`,
"f",
`ld\\.w \\$a0, \\$s7, 1000`);
codegenTestLOONG64_adhoc(
`(module
(memory 1)
(func (export "f") (result i32)
(i32.load offset=1000 (i32.const 1000))))`,
"f",
`ld\\.w \\$a0, \\$s7, 2000`);
codegenTestLOONG64_adhoc(
`(module
(memory 1)
(func (export "f") (param i32)
(i32.store (i32.const 1000) (local.get 0))))`,
"f",
`st\\.w \\$a0, \\$s7, 1000`);
codegenTestLOONG64_adhoc(
`(module
(memory 1)
(func (export "f") (param i32)
(i32.store offset=1000 (i32.const 1000) (local.get 0))))`,
"f",
`st\\.w \\$a0, \\$s7, 2000`);
// Friendly aligned si16 offsets can use ldptr.w.
codegenTestLOONG64_adhoc(
`(module
(memory 1)
(func (export "f") (result i32)
(i32.load (i32.const 4000))))`,
"f",
`ldptr\\.w \\$a0, \\$s7, 4000`);
codegenTestLOONG64_adhoc(
`(module
(memory 1)
(func (export "f") (result i32)
(i32.load offset=2000 (i32.const 4000))))`,
"f",
`ldptr\\.w \\$a0, \\$s7, 6000`);
// Offsets representable as two si12 immediates.
codegenTestLOONG64_adhoc(
`(module
(memory 1)
(func (export "f") (result i32)
(i32.load8_u (i32.const 4000))))`,
"f",
`addi\\.d \\$a0, \\$s7, 2000
ld\\.bu \\$a0, \\$a0, 2000`);
codegenTestLOONG64_adhoc(
`(module
(memory 1)
(func (export "f") (result i32)
(i32.load (i32.const 4001))))`,
"f",
`addi\\.d \\$a0, \\$s7, 2000
ld\\.w \\$a0, \\$a0, 2001`);
codegenTestLOONG64_adhoc(
`(module
(memory 1)
(func (export "f") (result i64)
(i64.load32_u (i32.const 4000))))`,
"f",
`addi\\.d \\$a0, \\$s7, 2000
ld\\.wu \\$a0, \\$a0, 2000`);
// Larger offsets are materialized in a register.
codegenTestLOONG64_adhoc(
`(module
(memory 1)
(func (export "f") (result i32)
(i32.load (i32.const 32768))))`,
"f",
`lu12i\\.w \\$a0, 8
ldx\\.w \\$a0, \\$s7, \\$a0`);
codegenTestLOONG64_adhoc(
`(module
(memory 1)
(func (export "f") (result i32)
(i32.load offset=2000 (i32.const 32768))))`,
"f",
`lu12i\\.w \\$a0, 8
ori \\$a0, \\$a0, 0x7d0
ldx\\.w \\$a0, \\$s7, \\$a0`);
// Stores
codegenTestLOONG64_adhoc(
`(module
(memory 1)
(func (export "f") (param i32)
(i32.store (i32.const 4000) (local.get 0))))`,
"f",
`stptr\\.w \\$a0, \\$s7, 4000`);
codegenTestLOONG64_adhoc(
`(module
(memory 1)
(func (export "f") (param i32)
(i32.store offset=1000 (i32.const 4000) (local.get 0))))`,
"f",
`stptr\\.w \\$a0, \\$s7, 5000`);
codegenTestLOONG64_adhoc(
`(module
(memory 1)
(func (export "f") (param i32)
(i32.store (i32.const 4001) (local.get 0))))`,
"f",
`addi\\.d \\$t6, \\$s7, 2000
st\\.w \\$a0, \\$t6, 2001`);
codegenTestLOONG64_adhoc(
`(module
(memory 1)
(func (export "f") (param i32)
(i32.store (i32.const 32768) (local.get 0))))`,
"f",
`lu12i\\.w \\$t6, 8
stx\\.w \\$a0, \\$s7, \\$t6`);
codegenTestLOONG64_adhoc(
`(module
(memory 1)
(func (export "f") (param i32)
(i32.store offset=1000 (i32.const 32768) (local.get 0))))`,
"f",
`lu12i\\.w \\$t6, 8
ori \\$t6, \\$t6, 0x3e8
stx\\.w \\$a0, \\$s7, \\$t6`);
// Various special cases.
// Offset is the largest positive Int32 materialized with only lu12i.w.
codegenTestLOONG64_adhoc(
`(module
(memory 1)
(func (export "f") (result i32)
(i32.load (i32.const 0x7fff_f000))))`,
"f",
`lu12i\\.w \\$a0, 524287
ldx\\.w \\$a0, \\$s7, \\$a0`,
{no_prefix: true});
// Adding one to the offset also requires ori.
codegenTestLOONG64_adhoc(
`(module
(memory 1)
(func (export "f") (result i32)
(i32.load (i32.const 0x7fff_f001))))`,
"f",
`lu12i\\.w \\$a0, 524287
ori \\$a0, \\$a0, 0x1
ldx\\.w \\$a0, \\$s7, \\$a0`,
{no_prefix: true});
// Offset is INT32_MAX.
codegenTestLOONG64_adhoc(
`(module
(memory 1)
(func (export "f") (result i32)
(i32.load (i32.const 0x7fff_ffff))))`,
"f",
`lu12i\\.w \\$a0, 524287
ori \\$a0, \\$a0, 0xfff
ldx\\.w \\$a0, \\$s7, \\$a0`,
{no_prefix: true});
// Static offset and dynamic offset are INT32_MAX.
codegenTestLOONG64_adhoc(
`(module
(memory 1)
(func (export "f") (result i32)
(i32.load offset=0x7fff_ffff (i32.const 0x7fff_ffff))))`,
"f",
`lu12i\\.w \\$t6, -1
bstrins\\.d \\$t6, \\$zero, 0x3f, 0x20
ori \\$t6, \\$t6, 0xffe
ldx\\.w \\$a0, \\$s7, \\$t6`,
{no_prefix: true});
// The combined address exceeds UINT32_MAX.
codegenTestLOONG64_adhoc(
`(module
(memory 1)
(func (export "f") (result i32)
(i32.load offset=1 (i32.const -1))))`,
"f",
`lu12i\\.w \\$t6, 0
lu32i\\.d \\$t6, 1
ldx\\.w \\$a0, \\$s7, \\$t6`,
{no_prefix: true});
// Offset is negative.
codegenTestLOONG64_adhoc(
`(module
(memory 1)
(func (export "f") (result i32)
(i32.load (i32.const -1))))`,
"f",
`lu12i\\.w \\$t6, -1
bstrins\\.d \\$t6, \\$zero, 0x3f, 0x20
ori \\$t6, \\$t6, 0xfff
ldx\\.w \\$a0, \\$s7, \\$t6`,
{no_prefix: true});
// Offset is INT32_MIN.
codegenTestLOONG64_adhoc(
`(module
(memory 1)
(func (export "f") (result i32)
(i32.load (i32.const 0x8000_0000))))`,
"f",
`lu12i\\.w \\$t6, -524288
bstrins\\.d \\$t6, \\$zero, 0x3f, 0x20
ldx\\.w \\$a0, \\$s7, \\$t6`,
{no_prefix: true});
// Other scalar types.
codegenTestLOONG64_adhoc(
`(module
(memory 1)
(func (export "f") (result i64)
(i64.load (i32.const 1000))))`,
"f",
`ld\\.d \\$a0, \\$s7, 1000`);
codegenTestLOONG64_adhoc(
`(module
(memory 1)
(func (export "f") (result i64)
(i64.load32_u (i32.const 1000))))`,
"f",
`ld\\.wu \\$a0, \\$s7, 1000`);
codegenTestLOONG64_adhoc(
`(module
(memory 1)
(func (export "f") (param i64)
(i64.store (i32.const 1000) (local.get 0))))`,
"f",
`st\\.d \\$a0, \\$s7, 1000`);
codegenTestLOONG64_adhoc(
`(module
(memory 1)
(func (export "f") (result f32)
(f32.load (i32.const 1000))))`,
"f",
`fld\\.s \\$f0, \\$s7, 1000`);
codegenTestLOONG64_adhoc(
`(module
(memory 1)
(func (export "f") (param f64)
(f64.store (i32.const 1000) (local.get 0))))`,
"f",
`fst\\.d \\$f0, \\$s7, 1000`);
// Other scalar types with materialized offsets.
codegenTestLOONG64_adhoc(
`(module
(memory 1)
(func (export "f") (result i32)
(i32.load8_u (i32.const 6000))))`,
"f",
`lu12i\\.w \\$a0, 1
ori \\$a0, \\$a0, 0x770
ldx\\.bu \\$a0, \\$s7, \\$a0`);
codegenTestLOONG64_adhoc(
`(module
(memory 1)
(func (export "f") (result i64)
(i64.load32_u (i32.const 6000))))`,
"f",
`lu12i\\.w \\$a0, 1
ori \\$a0, \\$a0, 0x770
ldx\\.wu \\$a0, \\$s7, \\$a0`);
codegenTestLOONG64_adhoc(
`(module
(memory 1)
(func (export "f") (result f32)
(f32.load (i32.const 6000))))`,
"f",
`lu12i\\.w \\$t6, 1
ori \\$t6, \\$t6, 0x770
fldx\\.s \\$f0, \\$s7, \\$t6`);
codegenTestLOONG64_adhoc(
`(module
(memory 1)
(func (export "f") (param f64)
(f64.store (i32.const 6000) (local.get 0))))`,
"f",
`lu12i\\.w \\$t6, 1
ori \\$t6, \\$t6, 0x770
fstx\\.d \\$f0, \\$s7, \\$t6`);