diff options
Diffstat (limited to 'vm/mterp/x86/OP_MUL_LONG.S')
-rw-r--r-- | vm/mterp/x86/OP_MUL_LONG.S | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/vm/mterp/x86/OP_MUL_LONG.S b/vm/mterp/x86/OP_MUL_LONG.S new file mode 100644 index 0000000..7cf6ccb --- /dev/null +++ b/vm/mterp/x86/OP_MUL_LONG.S @@ -0,0 +1,37 @@ +%verify "executed" + /* + * Signed 64-bit integer multiply. + * + * We could definately use more free registers for + * this code. We spill rINSTw (ebx), + * giving us eax, ebc, ecx and edx as computational + * temps. On top of that, we'll spill edi (rFP) + * for use as the vB pointer and esi (rPC) for use + * as the vC pointer. Yuck. + */ + /* mul-long vAA, vBB, vCC */ + movzbl 2(rPC),%eax # eax<- B + movzbl 3(rPC),%ecx # ecx<- C + SPILL_TMP2(%esi) # save Dalvik PC + SPILL(rFP) + SPILL(rINST) + SPILL(rIBASE) + leal (rFP,%eax,4),%esi # esi<- &v[B] + leal (rFP,%ecx,4),rFP # rFP<- &v[C] + movl 4(%esi),%ecx # ecx<- Bmsw + imull (rFP),%ecx # ecx<- (Bmsw*Clsw) + movl 4(rFP),%eax # eax<- Cmsw + imull (%esi),%eax # eax<- (Cmsw*Blsw) + addl %eax,%ecx # ecx<- (Bmsw*Clsw)+(Cmsw*Blsw) + movl (rFP),%eax # eax<- Clsw + mull (%esi) # eax<- (Clsw*Alsw) + UNSPILL(rINST) + UNSPILL(rFP) + leal (%ecx,rIBASE),rIBASE # full result now in rIBASE:%eax + UNSPILL_TMP2(%esi) # Restore Dalvik PC + FETCH_INST_OPCODE 2 %ecx # Fetch next instruction + movl rIBASE,4(rFP,rINST,4)# v[B+1]<- rIBASE + UNSPILL(rIBASE) + movl %eax,(rFP,rINST,4) # v[B]<- %eax + ADVANCE_PC 2 + GOTO_NEXT_R %ecx |