1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
|
From: Julian Seward <jseward@acm.org>
Date: Wed, 7 Aug 2024 10:43:53 +0200
Subject: Bug 1855960 - [MIPS64] Implement SummarizeTrapInstruction. r=jseward
Ref: https://bugzilla.mozilla.org/attachment.cgi?id=9365788&action=diff
Patch contributed by gur3n (Jiangjin Wang <the@salted.fish>)
Co-Authored-By: Zhao Jiazhong <zhaojiazhong-hf@loongson.cn>
Differential Revision: https://phabricator.services.mozilla.com/D195052
---
js/src/wasm/WasmGenerator.cpp | 7 +-
js/src/wasm/WasmSummarizeInsn.cpp | 175 ++++++++++++++++++++++++++++++
2 files changed, 179 insertions(+), 3 deletions(-)
diff --git a/js/src/wasm/WasmGenerator.cpp b/js/src/wasm/WasmGenerator.cpp
index d755c875..5ad977a 100644
--- a/js/src/wasm/WasmGenerator.cpp
+++ b/js/src/wasm/WasmGenerator.cpp
@@ -1081,12 +1081,13 @@ UniqueCodeTier ModuleGenerator::finishCodeTier() {
#if defined(DEBUG) && (defined(JS_CODEGEN_X64) || defined(JS_CODEGEN_X86) || \
defined(JS_CODEGEN_ARM64) || defined(JS_CODEGEN_ARM) || \
- defined(JS_CODEGEN_LOONG64))
+ defined(JS_CODEGEN_LOONG64) || \
+ defined(JS_CODEGEN_MIPS64))
// Check that each trapsite is associated with a plausible instruction. The
// required instruction kind depends on the trapsite kind.
//
- // NOTE: currently only enabled on x86_{32,64} and arm{32,64}. Ideally it
- // should be extended to riscv, loongson, mips.
+ // NOTE: currently enabled on x86_{32,64}, arm{32,64}, loongson64 and mips64.
+ // Ideally it should be extended to riscv64 too.
//
for (Trap trap : MakeEnumeratedRange(Trap::Limit)) {
const TrapSiteVector& trapSites = metadataTier_->trapSites[trap];
diff --git a/js/src/wasm/WasmSummarizeInsn.cpp b/js/src/wasm/WasmSummarizeInsn.cpp
index 99834d6..ae5eb70 100644
--- a/js/src/wasm/WasmSummarizeInsn.cpp
+++ b/js/src/wasm/WasmSummarizeInsn.cpp
@@ -1444,6 +1444,181 @@ Maybe<TrapMachineInsn> SummarizeTrapInstruction(const uint8_t* insnAddr) {
return Nothing();
}
+// ================================================================ mips64 ====
+
+# elif defined(JS_CODEGEN_MIPS64)
+
+Maybe<TrapMachineInsn> SummarizeTrapInstruction(const uint8_t* insnAddr) {
+ // Check instruction alignment.
+ MOZ_ASSERT(0 == (uintptr_t(insnAddr) & 3));
+
+ const uint32_t insn = *(uint32_t*)insnAddr;
+
+# define INSN(_maxIx, _minIx) \
+ ((insn >> (_minIx)) & ((uint32_t(1) << ((_maxIx) - (_minIx) + 1)) - 1))
+
+ // MIPS64R2 instruction encoding document:
+ // https://scc.ustc.edu.cn/_upload/article/files/c6/06/45556c084631b2855f0022175eaf/W020100308600769158777.pdf#G254.1001018
+
+ // MacroAssembler::wasmTrapInstruction uses this to create SIGILL.
+ // teq zero, zero, 0x6
+ if (insn == 0x000001b4) {
+ return Some(TrapMachineInsn::OfficialUD);
+ }
+
+ // MIPS64 Encoding of the Opcode Field of memory access instructions.
+ // +--------+--------------------------------------------------------+
+ // | bits | 28..26 |
+ // +--------+------+------+------+-------+------+------+------+------+
+ // | 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 |
+ // +--------+------+------+------+-------+------+------+------+------+
+ // | 010 | | | | COP1X | | | | |
+ // | 011 | | | LDL | LDR | | | | |
+ // | 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU |
+ // | 101 | SB | SH | SWL | SW | SDL | SDR | SWR | |
+ // | 110 | LL | LWC1 | LWC2 | | LLD | LDC1 | LDC2 | LD |
+ // | 111 | SC | SWC1 | SWC2 | | SCD | SDC1 | SDC2 | SD |
+ // +--------+------+------+------+-------+------+------+------+------+
+ if (INSN(31, 29) == 0b010) {
+ // MIPS64 COP1X Encoding of Function Field of memory access instructions.
+ // +--------+-----------------------------------------------------+
+ // | bits | 2..0 |
+ // +--------+-------+-------+-----+-----+-----+-------+-----+-----+
+ // | 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 |
+ // +--------+-------+-------+-----+-----+-----+-------+-----+-----+
+ // | 000 | LWXC1 | LDXC1 | | | | LUXC1 | | |
+ // | 001 | SWXC1 | SDXC1 | | | | SUXC1 | | |
+ // +--------+-------+-------+-----+-----+-----+-------+-----+-----+
+ switch (INSN(5, 0)) {
+ // lwxc1
+ case 0b000000:
+ return Some(TrapMachineInsn::Load32);
+ // ldxc1
+ case 0b000001:
+ // luxc1
+ case 0b000101:
+ return Some(TrapMachineInsn::Load64);
+ // swxc1
+ case 0b001000:
+ return Some(TrapMachineInsn::Store32);
+ // sdxc1
+ case 0b001001:
+ // suxc1
+ case 0b001101:
+ return Some(TrapMachineInsn::Store64);
+ default:
+ break;
+ }
+ } else if (INSN(31, 29) == 0b011) {
+ switch (INSN(28, 26)) {
+ // ldl
+ case 0b010:
+ // ldr
+ case 0b011:
+ return Some(TrapMachineInsn::Load64);
+ default:
+ break;
+ }
+ } else if (INSN(31, 29) == 0b100) {
+ switch (INSN(28, 26)) {
+ // lb
+ case 0b000:
+ return Some(TrapMachineInsn::Load8);
+ // lh
+ case 0b001:
+ return Some(TrapMachineInsn::Load16);
+ // lwl
+ case 0b010:
+ // lw
+ case 0b011:
+ return Some(TrapMachineInsn::Load32);
+ // lbu
+ case 0b100:
+ return Some(TrapMachineInsn::Load8);
+ // lhu
+ case 0b101:
+ return Some(TrapMachineInsn::Load16);
+ // lwr
+ case 0b110:
+ // lwu
+ case 0b111:
+ return Some(TrapMachineInsn::Load32);
+ }
+ } else if (INSN(31, 29) == 0b101) {
+ switch (INSN(28, 26)) {
+ // sb
+ case 0b000:
+ return Some(TrapMachineInsn::Store8);
+ // sh
+ case 0b001:
+ return Some(TrapMachineInsn::Store16);
+ // swl
+ case 0b010:
+ // sw
+ case 0b011:
+ return Some(TrapMachineInsn::Store32);
+ // sdl
+ case 0b100:
+ // sdr
+ case 0b101:
+ return Some(TrapMachineInsn::Store64);
+ // swr
+ case 0b110:
+ return Some(TrapMachineInsn::Store32);
+ // cache
+ case 0b111:
+ break;
+ }
+ } else if (INSN(31, 29) == 0b110) {
+ switch (INSN(28, 26)) {
+ // ll
+ case 0b000:
+ // lwc1
+ case 0b001:
+ // lwc2
+ case 0b010:
+ return Some(TrapMachineInsn::Load32);
+ // pref
+ case 0b011:
+ break;
+ // lld
+ case 0b100:
+ // ldc1
+ case 0b101:
+ // ldc2
+ case 0b110:
+ // ld
+ case 0b111:
+ return Some(TrapMachineInsn::Load64);
+ }
+ } else if (INSN(31, 29) == 0b111) {
+ switch (INSN(28, 26)) {
+ // sc
+ case 0b000:
+ // swc1
+ case 0b001:
+ // swc2
+ case 0b010:
+ return Some(TrapMachineInsn::Store32);
+ // reserved encoding
+ case 0b011:
+ break;
+ // scd
+ case 0b100:
+ // sdc1
+ case 0b101:
+ // sdc2
+ case 0b110:
+ // sd
+ case 0b111:
+ return Some(TrapMachineInsn::Store64);
+ }
+ }
+
+# undef INSN
+ return Nothing();
+}
+
// ================================================================== none ====
# elif defined(JS_CODEGEN_NONE)
|