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: binopDLit16.S
     18     *
     19     * Code: 32-bit "lit16" divide operation. If "div" is set, the code
     20     *       returns the quotient, else it returns the remainder.
     21     *       Also, a divide-by-zero check is done.
     22     *
     23     * For: div-int/lit16, rem-int/lit16
     24     *
     25     * Description: Perform a binary operation on a register and a
     26     *              sign extended 16-bit literal value
     27     *
     28     * Format: B|A|op CCCC (22s)
     29     *
     30     * Syntax: op vA, vB, #+CCCC
     31     */
     32 
     33 %default {"div":"1"}
     34 
     35     movl        rINST, %eax             # %eax<- BA
     36     shr         $$4, %eax               # %eax<- B
     37     FETCHs      1, %ecx                 # %ecx<- +CCCC, sign-extended literal
     38     cmp         $$0, %ecx               # check for divide by zero
     39     GET_VREG    %eax                    # %eax<- vB
     40     je          common_errDivideByZero  # handle divide by zero
     41     andl        $$15, rINST             # rINST<- A
     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     #FFETCH_ADV 2, %ecx                 # %ecx<- next instruction hi; fetch, advance
     50     .if  $div
     51     SET_VREG    %eax rINST              # vA<- %eax (quotient)
     52     .else
     53     SET_VREG    %edx rINST              # vA<- %edx (remainder)
     54     .endif
     55     jmp         .L${opcode}_break2
     56 
     57 %break
     58 .L${opcode}_break:
     59     .if  $div
     60     movl        $$0x80000000, (rFP, rINST, 4) # vAA<- min int
     61     .else
     62     movl        $$0, (rFP, rINST, 4)    # vAA<- 0
     63     .endif
     64 .L${opcode}_break2:
     65 
     66     FINISH      2                       # jump to next instruction
     67