Home | History | Annotate | Download | only in arm
      1     /*
      2      * Signed 64-bit integer multiply.
      3      *
      4      * Consider WXxYZ (r1r0 x r3r2) with a long multiply:
      5      *        WX
      6      *      x YZ
      7      *  --------
      8      *     ZW ZX
      9      *  YW YX
     10      *
     11      * The low word of the result holds ZX, the high word holds
     12      * (ZW+YX) + (the high overflow from ZX).  YW doesn't matter because
     13      * it doesn't fit in the low 64 bits.
     14      *
     15      * Unlike most ARM math operations, multiply instructions have
     16      * restrictions on using the same register more than once (Rd and Rm
     17      * cannot be the same).
     18      */
     19     /* mul-long vAA, vBB, vCC */
     20     FETCH r0, 1                         @ r0<- CCBB
     21     and     r2, r0, #255                @ r2<- BB
     22     mov     r3, r0, lsr #8              @ r3<- CC
     23     VREG_INDEX_TO_ADDR r2, r2           @ r2<- &fp[BB]
     24     VREG_INDEX_TO_ADDR r3, r3           @ r3<- &fp[CC]
     25     ldmia   r2, {r0-r1}                 @ r0/r1<- vBB/vBB+1
     26     ldmia   r3, {r2-r3}                 @ r2/r3<- vCC/vCC+1
     27     mul     ip, r2, r1                  @ ip<- ZxW
     28     umull   r1, lr, r2, r0              @ r1/lr <- ZxX
     29     mla     r2, r0, r3, ip              @ r2<- YxX + (ZxW)
     30     mov     r0, rINST, lsr #8           @ r0<- AA
     31     add     r2, r2, lr                  @ r2<- lr + low(ZxW + (YxX))
     32     VREG_INDEX_TO_ADDR r0, r0           @ r0<- &fp[AA]
     33     FETCH_ADVANCE_INST 2                @ advance rPC, load rINST
     34     GET_INST_OPCODE ip                  @ extract opcode from rINST
     35     stmia   r0, {r1-r2 }                @ vAA/vAA+1<- r1/r2
     36     GOTO_OPCODE ip                      @ jump to next instruction
     37