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: binopD2addr.S
     18     *
     19     * Code: 32-bit "/2addr" integer divde operation. If "div"
     20     *       is set, the code returns the quotient, else it returns
     21     *       the remainder. Also, a divide-by-zero check is done.
     22     *
     23     * For: div-int/2addr, rem-int/2addr
     24     *
     25     * Description: Perform a binary operation on two sources registers
     26     *              and store the result in the first source register
     27     *
     28     * Format: B|A|op (12x)
     29     *
     30     * Syntax: op vA, vB
     31     */
     32 
     33 %default {"div":"1"}
     34     movl        rINST, %ecx             # %ecx<- BA
     35     andl        $$15, rINST             # rINST<- A, to be used as dest
     36     movl        rINST, %eax             # %eax<- A
     37     shr         $$4, %ecx               # %ecx<- B
     38     GET_VREG    %eax                    # %eax<- vA
     39     GET_VREG    %ecx                    # %edx<- vB
     40     cmp         $$0, %ecx               # check for divide by zero
     41     je          common_errDivideByZero  # handle divide by zero
     42     cmpl        $$-1, %ecx              # handle -1 special case divide error
     43     jne         .L${opcode}_noerror
     44     cmpl        $$0x80000000,%eax       # handle min int special case divide error
     45     je         .L${opcode}_break
     46 .L${opcode}_noerror:
     47     cdq                                 # sign-extend %eax to %edx
     48     idiv        %ecx                    # divide %edx:%eax by %ecx
     49      .if  $div
     50     SET_VREG    %eax rINST              # vAA<- %eax (quotient)
     51     .else
     52     SET_VREG    %edx rINST              # vAA<- %edx (remainder)
     53     .endif
     54     jmp         .L${opcode}_break2
     55     #FFETCH_ADV 1, %edx  # %ecx<- next instruction hi; fetch, advance
     56     #FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
     57 
     58 %break
     59 .L${opcode}_break:
     60     .if  $div
     61     movl        $$0x80000000, (rFP, rINST, 4) # vAA<- min int
     62     .else
     63     movl        $$0, (rFP, rINST, 4)    # vAA<- 0
     64     .endif
     65 .L${opcode}_break2:
     66     FFETCH_ADV  1, %edx                 # %ecx<- next instruction hi; fetch, advance
     67     FGETOP_JMP  1, %edx                 # jump to next instruction; getop, jmp
     68 
     69