100b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze%default { "func":"MterpDoPackedSwitch" } 200b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze /* 300b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze * Handle a packed-switch or sparse-switch instruction. In both cases 400b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze * we decode it and hand it off to a helper function. 500b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze * 600b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze * We don't really expect backward branches in a switch statement, but 700b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze * they're perfectly legal, so we check for them here. 800b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze * 900b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze * for: packed-switch, sparse-switch 1000b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze */ 1100b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze /* op vAA, +BBBBBBBB */ 1200b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze .extern $func 13db045bea24d28ce6ad932fec4ce055af7be530e2Alexey Frunze .extern MterpProfileBranch 1400b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze lh a0, 2(rPC) # a0 <- bbbb (lo) 1500b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze lh a1, 4(rPC) # a1 <- BBBB (hi) 1600b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze srl a3, rINST, 8 # a3 <- AA 1700b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze ins a0, a1, 16, 16 # a0 <- BBBBbbbb 1800b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze GET_VREG a1, a3 # a1 <- vAA 1900b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze dlsa a0, a0, rPC, 1 # a0 <- PC + BBBBbbbb*2 2000b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze jal $func # v0 <- code-unit branch offset 21db045bea24d28ce6ad932fec4ce055af7be530e2Alexey Frunze move rINST, v0 22db045bea24d28ce6ad932fec4ce055af7be530e2Alexey Frunze#if MTERP_PROFILE_BRANCHES 23db045bea24d28ce6ad932fec4ce055af7be530e2Alexey Frunze EXPORT_PC 24db045bea24d28ce6ad932fec4ce055af7be530e2Alexey Frunze move a0, rSELF 25db045bea24d28ce6ad932fec4ce055af7be530e2Alexey Frunze daddu a1, rFP, OFF_FP_SHADOWFRAME 26db045bea24d28ce6ad932fec4ce055af7be530e2Alexey Frunze move a2, rINST 27db045bea24d28ce6ad932fec4ce055af7be530e2Alexey Frunze jal MterpProfileBranch # (self, shadow_frame, offset) 28db045bea24d28ce6ad932fec4ce055af7be530e2Alexey Frunze bnezc v0, MterpOnStackReplacement # Note: offset must be in rINST 2900b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze#endif 30db045bea24d28ce6ad932fec4ce055af7be530e2Alexey Frunze dlsa rPC, rINST, rPC, 1 # rPC <- rPC + offset * 2 31db045bea24d28ce6ad932fec4ce055af7be530e2Alexey Frunze lw ra, THREAD_FLAGS_OFFSET(rSELF) # Preload flags for MterpCheckSuspendAndContinue 32db045bea24d28ce6ad932fec4ce055af7be530e2Alexey Frunze move a0, rINST # a0 <- offset 33db045bea24d28ce6ad932fec4ce055af7be530e2Alexey Frunze FETCH_INST # load rINST 34db045bea24d28ce6ad932fec4ce055af7be530e2Alexey Frunze blez a0, MterpCheckSuspendAndContinue # suspend check if backwards branch 3500b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze GET_INST_OPCODE v0 # extract opcode from rINST 3600b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze GOTO_OPCODE v0 # jump to next instruction 37