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("riscv64"); include:codegen-riscv64-test.js
// Test that loads/stores at friendly constant offsets yield expected code.
//
// WASM HeapReg is "s7".
codegenTestRISCV64_adhoc(
`(module
(memory 1)
(func (export "f") (result i32)
(i32.load (i32.const 1000))))`,
"f",
`lw a0, 1000\\(s7\\)`);
codegenTestRISCV64_adhoc(
`(module
(memory 1)
(func (export "f") (result i32)
(i32.load offset=1000 (i32.const 1000))))`,
"f",
`lw a0, 2000\\(s7\\)`);
codegenTestRISCV64_adhoc(
`(module
(memory 1)
(func (export "f") (param i32)
(i32.store (i32.const 1000) (local.get 0))))`,
"f",
`sw a0, 1000\\(s7\\)`);
codegenTestRISCV64_adhoc(
`(module
(memory 1)
(func (export "f") (param i32)
(i32.store offset=1000 (i32.const 1000) (local.get 0))))`,
"f",
`sw a0, 2000\\(s7\\)`);
// Unfriendly offsets are first loaded into a scratch register.
codegenTestRISCV64_adhoc(
`(module
(memory 1)
(func (export "f") (result i32)
(i32.load (i32.const 4000))))`,
"f",
`addi t4, s7, 2000
lw a0, 2000\\(t4\\)`);
codegenTestRISCV64_adhoc(
`(module
(memory 1)
(func (export "f") (result i32)
(i32.load offset=2000 (i32.const 4000))))`,
"f",
`lui t4, 0x1
add t4, s7, t4
lw a0, 1904\\(t4\\)`);
// Stores
codegenTestRISCV64_adhoc(
`(module
(memory 1)
(func (export "f") (param i32)
(i32.store (i32.const 4000) (local.get 0))))`,
"f",
`addi t4, s7, 2000
sw a0, 2000\\(t4\\)`);
codegenTestRISCV64_adhoc(
`(module
(memory 1)
(func (export "f") (param i32)
(i32.store offset=1000 (i32.const 4000) (local.get 0))))`,
"f",
`lui t4, 0x1
add t4, s7, t4
sw a0, 904\\(t4\\)`);
// Various special cases.
// Offset is largest positive Int32 which requires no full materialization.
codegenTestRISCV64_adhoc(
`(module
(memory 1)
(func (export "f") (result i32)
(i32.load (i32.const 0x7fff_f7ff))))`,
"f",
`lui t4, 0x7ffff
add t4, s7, t4
lw a0, 2047\\(t4\\)`,
{no_prefix: true});
// Offset is smallest positive Int32 which requires full materialization.
codegenTestRISCV64_adhoc(
`(module
(memory 1)
(func (export "f") (result i32)
(i32.load (i32.const 0x7fff_f800))))`,
"f",
`lui t4, 0xfff80000
addiw t4, t4, -2048
add t4, s7, t4
lw a0, 0\\(t4\\)`,
{no_prefix: true});
// Offset is INT32_MAX.
codegenTestRISCV64_adhoc(
`(module
(memory 1)
(func (export "f") (result i32)
(i32.load (i32.const 0x7fff_ffff))))`,
"f",
`lui t4, 0xfff80000
addiw t4, t4, -1
add t4, s7, t4
lw a0, 0\\(t4\\)`,
{no_prefix: true});
// Static offset and dynamic offset are INT32_MAX.
codegenTestRISCV64_adhoc(
`(module
(memory 1)
(func (export "f") (result i32)
(i32.load offset=0x7fff_ffff (i32.const 0x7fff_ffff))))`,
"f",
`(li t4, 1
slli t4, t4, 32
addi t4, t4, -2)
| (li t4, -2
zext.w t4, t4)
add t5, s7, t4
lw a0, 0\\(t5\\)`,
{no_prefix: true});
// Offset is negative.
codegenTestRISCV64_adhoc(
`(module
(memory 1)
(func (export "f") (result i32)
(i32.load (i32.const -1))))`,
"f",
`li t4, -1
srli t4, t4, 32
add t5, s7, t4
lw a0, 0\\(t5\\)`,
{no_prefix: true});
// Offset is INT32_MIN.
codegenTestRISCV64_adhoc(
`(module
(memory 1)
(func (export "f") (result i32)
(i32.load (i32.const 0x8000_0000))))`,
"f",
`(li t4, 1
slli t4, t4, 31)
| (bseti t4, zero, 31)
add t5, s7, t4
lw a0, 0\\(t5\\)`,
{no_prefix: true});