Home | History | Annotate | Download | only in x86-atom
      1    /* Copyright (C) 2008 The Android Open Source Project
      2     *
      3     * Licensed under the Apache License, Version 2.0 (the "License");
      4     * you may not use this file except in compliance with the License.
      5     * You may obtain a copy of the License at
      6     *
      7     * http://www.apache.org/licenses/LICENSE-2.0
      8     *
      9     * Unless required by applicable law or agreed to in writing, software
     10     * distributed under the License is distributed on an "AS IS" BASIS,
     11     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12     * See the License for the specific language governing permissions and
     13     * limitations under the License.
     14     */
     15 
     16    /*
     17     * File: OP_MUL_LONG.S
     18     *
     19     * Code: 64-bit integer multiply
     20     *
     21     * For: mul-long
     22     *
     23     * Description: Multiply two source registers and store the
     24     *              result in a destination register.
     25     *
     26     * Format: AA|op CC|BB (23x)
     27     *
     28     * Syntax: op vAA, vBB, vCC
     29     */
     30 
     31    /*
     32     * Signed 64-bit integer multiply.
     33     *
     34     * Consider WXxYZ (r1r0 x r3r2) with a long multiply:
     35     *        WX
     36     *      x YZ
     37     *  --------
     38     *     ZW ZX
     39     *  YW YX
     40     *
     41     * The low word of the result holds ZX, the high word holds
     42     * (ZW+YX) + (the high overflow from ZX).  YW doesn't matter because
     43     * it doesn't fit in the low 64 bits.
     44     */
     45 
     46     movl        rINST, -4(%esp)         # -4(%esp)<- AA+
     47     FETCH_BB    1, rINST                # rINST<- BB
     48     FETCH_CC    1, %edx                 # %edx<- CC
     49     jmp         .L${opcode}_finish
     50 %break
     51 
     52    /*
     53     * X = (rFP, rINST, 4)
     54     * W = 4(rFP, rINST, 4)
     55     * Z = (rFP, %edx, 4)
     56     * Y = 4(rFP, %edx, 4)
     57     */
     58 
     59 .L${opcode}_finish:
     60     movl        4(rFP, rINST, 4), %ecx  # %ecx<- W
     61     imull       (rFP, %edx, 4),  %ecx   # %ecx<- WxZ
     62     mov         4(rFP, %edx, 4), %eax   # %ecx<- Y
     63     imull       (rFP, rINST, 4), %eax   # %eax<- XxY
     64     addl        %eax, %ecx              # %ecx<- (WZ + XY)
     65     movl        (rFP, %edx, 4), %eax    # %eax<- Z
     66     mull        (rFP, rINST, 4)         # %edx:eax<- XZ
     67     movzbl      -4(%esp), rINST         # rINST<- AA
     68     addl        %edx, %ecx              # %ecx<- carry + (WZ + XY)
     69     movl        %ecx, 4(rFP, rINST, 4)  # vAA+1<- results hi
     70     movl        %eax, (rFP, rINST, 4)   # vAA<- results lo
     71     FINISH      2                       # jump to next instruction
     72