1 /* 2 * Unconditional branch, 32-bit offset. 3 * 4 * The branch distance is a signed code-unit offset, which we need to 5 * double to get a byte offset. 6 * 7 * Unlike most opcodes, this one is allowed to branch to itself, so 8 * our "backward branch" test must be "<=0" instead of "<0". 9 */ 10 /* goto/32 +AAAAAAAA */ 11 #if MTERP_PROFILE_BRANCHES 12 FETCH(a0, 1) # a0 <- aaaa (lo) 13 FETCH(a1, 2) # a1 <- AAAA (hi) 14 sll a1, a1, 16 15 or rINST, a0, a1 # rINST <- AAAAaaaa 16 EXPORT_PC() 17 move a0, rSELF 18 addu a1, rFP, OFF_FP_SHADOWFRAME 19 move a2, rINST 20 JAL(MterpProfileBranch) # (self, shadow_frame, offset) 21 bnez v0, MterpOnStackReplacement # Note: offset must be in rINST 22 addu a1, rINST, rINST # a1 <- byte offset 23 FETCH_ADVANCE_INST_RB(a1) # update rPC, load rINST 24 bgtz a1, 1f 25 lw ra, THREAD_FLAGS_OFFSET(rSELF) 26 b MterpCheckSuspendAndContinue 27 1: 28 GET_INST_OPCODE(t0) # extract opcode from rINST 29 GOTO_OPCODE(t0) # jump to next instruction 30 #else 31 FETCH(a0, 1) # a0 <- aaaa (lo) 32 FETCH(a1, 2) # a1 <- AAAA (hi) 33 sll a1, a1, 16 34 or rINST, a0, a1 # rINST <- AAAAaaaa 35 addu a1, rINST, rINST # a1 <- byte offset 36 FETCH_ADVANCE_INST_RB(a1) # update rPC, load rINST 37 bgtz a1, 1f 38 lw ra, THREAD_FLAGS_OFFSET(rSELF) 39 b MterpCheckSuspendAndContinue 40 1: 41 GET_INST_OPCODE(t0) # extract opcode from rINST 42 GOTO_OPCODE(t0) # jump to next instruction 43 #endif 44