Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Android/art/art/runtime/interpreter/mterp/x86_64ng/   (Android Betriebssystem Version 17©)  Datei vom 26.5.2026 mit Größe 17 kB image not shown  

Quelle  arithmetic.S

  Sprache: Sparc
 

%def bindiv(result="", second="", tmp="", wide=False, suffix="", rem=False, ext="cdq"):
/*
 * 32-bit binary div/rem operation.  Handles special case of op1=-1.
 */

    /* div/rem vAA, vBB, vCC */
    movzbq  2(rPC), %rax                    # rax <- BB
    movzbq  3(rPC), %rcx                    # rcx <- CC
%   if wide:
      GET_WIDE_VREG %rax, %rax              # eax <- vBB
      GET_WIDE_VREG $second, %rcx           # ecx <- vCC
%   else:
      GET_VREG %eax, %rax                   # eax <- vBB
      GET_VREG $second, %rcx                # ecx <- vCC
    test${suffix}   $second, $second
    jz      common_errDivideByZero
    cmp${suffix}  $$-1, $second
    je      2f
    cmp${suffix}  $$2, $second
    je 3f
    $ext                                    # rdx:rax <- sign-extended of rax
    idiv${suffix}   $second
1:
%   if wide:
      SET_WIDE_VREG $result, rINSTq         # eax <- vBB
%   else:
      SET_VREG $result, rINSTq              # eax <- vBB
    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
2:
%   if rem:
      xor${suffix} $result, $result
%   else:
      neg${suffix} $result
    jmp     1b
3:
%   if rem:
      mov${suffix} $tmp, $result
%     if wide:
        shr${suffix} $$63, $result
%     else:
        shr${suffix} $$31, $result
      add${suffix} $tmp, $result
      and${suffix} $$-2, $result
      sub${suffix} $result, $tmp
      mov${suffix} $tmp, $result
%   else:
      mov${suffix} $result, $tmp
%     if wide:
        shr${suffix} $$63, $tmp
%     else:
        shr${suffix} $$31, $tmp
      add${suffix} $tmp, $result
      sar${suffix} $result
    jmp     1b

%def bindiv2addr(result="", second="", tmp="", wide=False, suffix="", rem=False, ext="cdq"):
/*
 * 32-bit binary div/rem operation.  Handles special case of op1=-1.
 */

    /* div/rem/2addr vA, vB */
    movl    rINST, %ecx                     # rcx <- BA
    sarl    $$4, %ecx                       # rcx <- B
    andb    $$0xf, rINSTbl                  # rINST <- A
%   if wide:
      GET_WIDE_VREG %rax, rINSTq            # eax <- vA
      GET_WIDE_VREG $second, %rcx           # ecx <- vB
%   else:
      GET_VREG %eax, rINSTq                 # eax <- vA
      GET_VREG $second, %rcx                # ecx <- vB
    test${suffix}   $second, $second
    jz      common_errDivideByZero
    cmp${suffix}  $$-1, $second
    je      2f
    cmp${suffix}  $$2, $second
    je      3f
    $ext                                    # rdx:rax <- sign-extended of rax
    idiv${suffix}   $second
1:
%   if wide:
      SET_WIDE_VREG $result, rINSTq         # vA <- result
%   else:
      SET_VREG $result, rINSTq              # vA <- result
    ADVANCE_PC_FETCH_AND_GOTO_NEXT 1
2:
%   if rem:
      xor${suffix} $result, $result
%   else:
      neg${suffix} $result
    jmp     1b
3:
%   if rem:
      mov${suffix} $tmp, $result
%     if wide:
        shr${suffix} $$63, $result
%     else:
        shr${suffix} $$31, $result
      add${suffix} $tmp, $result
      and${suffix} $$-2, $result
      sub${suffix} $result, $tmp
      mov${suffix} $tmp, $result
%   else:
      mov${suffix} $result, $tmp
%     if wide:
        shr${suffix} $$63, $tmp
%     else:
        shr${suffix} $$31, $tmp
      add${suffix} $tmp, $result
      sar${suffix} $result
    jmp     1b

%def bindivLit16(result="", rem=False):
/*
 * 32-bit binary div/rem operation.  Handles special case of op1=-1.
 */

    /* div/rem/lit16 vA, vB, #+CCCC */
    /* Need A in rINST, ssssCCCC in ecx, vB in eax */
    movl    rINST, %eax                     # rax <- 000000BA
    sarl    $$4, %eax                       # eax <- B
    GET_VREG %eax, %rax                     # eax <- vB
    movswl  2(rPC), %ecx                    # ecx <- ssssCCCC
    andb    $$0xf, rINSTbl                  # rINST <- A
    testl   %ecx, %ecx
    jz      common_errDivideByZero
    cmpl    $$-1, %ecx
    je      2f
    cdq                                     # rax <- sign-extended of eax
    idivl   %ecx
1:
    SET_VREG $result, rINSTq                # vA <- result
    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
2:
%   if rem:
      xorl    $result, $result
%   else:
      negl    $result
    jmp     1b

%def bindivLit8(result="", rem=False):
/*
 * 32-bit div/rem "lit8" binary operation.  Handles special case of
 * op0=minint & op1=-1
 */

    /* div/rem/lit8 vAA, vBB, #+CC */
    movzbq  2(rPC), %rax                    # eax <- BB
    movsbl  3(rPC), %ecx                    # ecx <- ssssssCC
    GET_VREG  %eax, %rax                    # eax <- rBB
    testl   %ecx, %ecx
    je      common_errDivideByZero
    cmpl    $$-1, %ecx
    je      2f
    cdq                                     # rax <- sign-extended of eax
    idivl   %ecx
1:
    SET_VREG $result, rINSTq                # vA <- result
    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
2:
%   if rem:
      xorl    $result, $result
%   else:
      negl    $result
    jmp     1b

%def binop(result="%eax", instr=""):
/*
 * Generic 32-bit binary operation.  Provide an "instr" line that
 * specifies an instruction that performs "result = eax op (rFP,%ecx,4)".
 * This could be an x86 instruction or a function call.  (If the result
 * comes back in a register other than eax, you can override "result".)
 *
 * For: add-int, sub-int, and-int, or-int,
 *      xor-int, shl-int, shr-int, ushr-int
 */

    /* binop vAA, vBB, vCC */
    movzbq  2(rPC), %rax                    # rax <- BB
    movzbq  3(rPC), %rcx                    # rcx <- CC
    GET_VREG %eax, %rax                     # eax <- vBB
    $instr VREG_ADDRESS(%rcx),%eax
    SET_VREG $result, rINSTq
    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2

%def binop1(wide=False, instr=""):
/*
 * Generic 32-bit binary operation in which both operands loaded to
 * registers (op0 in eax, op1 in ecx).
 */

    /* binop vAA, vBB, vCC */
    movzbq  2(rPC), %rax                    # eax <- BB
    movzbq  3(rPC), %rcx                    # ecx <- CC
    GET_VREG %ecx, %rcx                     # eax <- vCC
%   if wide:
      GET_WIDE_VREG %rax, %rax              # rax <- vBB
      $instr                                # ex: addl    %ecx,%eax
      SET_WIDE_VREG %rax, rINSTq
%   else:
      GET_VREG %eax, %rax                   # eax <- vBB
      $instr                                # ex: addl    %ecx,%eax
      SET_VREG %eax, rINSTq
    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2

%def binop2addr(result="%eax", instr=""):
/*
 * Generic 32-bit "/2addr" binary operation.  Provide an "instr" line
 * that specifies an instruction that performs "result = r0 op r1".
 * This could be an instruction or a function call.
 *
 * For: add-int/2addr, sub-int/2addr, mul-int/2addr, div-int/2addr,
 *      rem-int/2addr, and-int/2addr, or-int/2addr, xor-int/2addr,
 *      shl-int/2addr, shr-int/2addr, ushr-int/2addr, add-float/2addr,
 *      sub-float/2addr, mul-float/2addr, div-float/2addr, rem-float/2addr
 */

    /* binop/2addr vA, vB */
    movl    rINST, %ecx                     # rcx <- A+
    sarl    $$4, rINST                      # rINST <- B
    andb    $$0xf, %cl                      # ecx <- A
    GET_VREG %eax, rINSTq                   # eax <- vB
    $instr %eax, VREG_ADDRESS(%rcx)
    CLEAR_REF %rcx
    ADVANCE_PC_FETCH_AND_GOTO_NEXT 1

%def binopLit16(result="%eax", instr=""):
/*
 * Generic 32-bit "lit16" binary operation.  Provide an "instr" line
 * that specifies an instruction that performs "result = eax op ecx".
 * This could be an x86 instruction or a function call.  (If the result
 * comes back in a register other than eax, you can override "result".)
 *
 * For: add-int/lit16, rsub-int,
 *      and-int/lit16, or-int/lit16, xor-int/lit16
 */

    /* binop/lit16 vA, vB, #+CCCC */
    movl    rINST, %eax                     # rax <- 000000BA
    sarl    $$4, %eax                       # eax <- B
    GET_VREG %eax, %rax                     # eax <- vB
    andb    $$0xf, rINSTbl                  # rINST <- A
    movswl  2(rPC), %ecx                    # ecx <- ssssCCCC
    $instr                                  # for example: addl %ecx, %eax
    SET_VREG $result, rINSTq
    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2

%def binopLit8(result="%eax", instr=""):
/*
 * Generic 32-bit "lit8" binary operation.  Provide an "instr" line
 * that specifies an instruction that performs "result = eax op ecx".
 * This could be an x86 instruction or a function call.  (If the result
 * comes back in a register other than r0, you can override "result".)
 *
 * For: add-int/lit8, rsub-int/lit8
 *      and-int/lit8, or-int/lit8, xor-int/lit8,
 *      shl-int/lit8, shr-int/lit8, ushr-int/lit8
 */

    /* binop/lit8 vAA, vBB, #+CC */
    movzbq  2(rPC), %rax                    # rax <- BB
    movsbl  3(rPC), %ecx                    # rcx <- ssssssCC
    GET_VREG %eax, %rax                     # eax <- rBB
    $instr                                  # ex: addl %ecx,%eax
    SET_VREG $result, rINSTq
    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2

%def binopWide(instr=""):
/*
 * Generic 64-bit binary operation.
 */

    /* binop vAA, vBB, vCC */
    movzbq  2(rPC), %rax                    # eax <- BB
    movzbq  3(rPC), %rcx                    # ecx <- CC
    GET_WIDE_VREG %rax, %rax                # rax <- v[BB]
    $instr VREG_ADDRESS(%rcx),%rax
    SET_WIDE_VREG %rax, rINSTq              # v[AA] <- rax
    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2

%def binopWide2addr(instr=""):
/*
 * Generic 64-bit binary operation.
 */

    /* binop/2addr vA, vB */
    movl    rINST, %ecx                     # rcx <- A+
    sarl    $$4, rINST                      # rINST <- B
    andb    $$0xf, %cl                      # ecx <- A
    GET_WIDE_VREG %rax, rINSTq              # rax <- vB
    $instr %rax,VREG_ADDRESS(%rcx)
    CLEAR_WIDE_REF %rcx
    ADVANCE_PC_FETCH_AND_GOTO_NEXT 1

%def cvtfp_int(fp_suffix="", i_suffix="", max_const="", result_reg="", wide=False):
/* On fp to int conversions, Java requires that
 * if the result > maxint, it should be clamped to maxint.  If it is less
 * than minint, it should be clamped to minint.  If it is a nan, the result
 * should be zero.  Further, the rounding mode is to truncate.
 */

    /* float/double to int/long vA, vB */
    movl    rINST, %ecx                     # rcx <- A+
    sarl    $$4, rINST                      # rINST <- B
    andb    $$0xf, %cl                      # ecx <- A
    GET_VREG_XMM${fp_suffix} %xmm0, rINSTq
    mov${i_suffix}  ${max_const}, ${result_reg}
    cvtsi2s${fp_suffix}${i_suffix} ${result_reg}, %xmm1
    comis${fp_suffix}    %xmm1, %xmm0
    jae     1f
    jp      2f
    cvtts${fp_suffix}2si${i_suffix}  %xmm0, ${result_reg}
    jmp     1f
2:
    xor${i_suffix}    ${result_reg}, ${result_reg}
1:
%   if wide:
      SET_WIDE_VREG ${result_reg}, %rcx
%   else:
      SET_VREG ${result_reg}, %rcx
    ADVANCE_PC_FETCH_AND_GOTO_NEXT 1

%def shop2addr(wide=False, instr=""):
/*
 * Generic 32-bit "shift/2addr" operation.
 */

    /* shift/2addr vA, vB */
    movl    rINST, %ecx                     # ecx <- BA
    sarl    $$4, %ecx                       # ecx <- B
    GET_VREG %ecx, %rcx                     # ecx <- vBB
    andb    $$0xf, rINSTbl                  # rINST <- A
%   if wide:
      GET_WIDE_VREG %rax, rINSTq            # rax <- vAA
      $instr                                # ex: sarl %cl, %eax
      SET_WIDE_VREG %rax, rINSTq
%   else:
      GET_VREG %eax, rINSTq                 # eax <- vAA
      $instr                                # ex: sarl %cl, %eax
      SET_VREG %eax, rINSTq
    ADVANCE_PC_FETCH_AND_GOTO_NEXT 1

%def unop(preinstr="", instr="", wide=False):
/*
 * Generic 32/64-bit unary operation.  Provide an "instr" line that
 * specifies an instruction that performs "result = op eax".
 */

    /* unop vA, vB */
    movl    rINST, %ecx                     # rcx <- A+
    sarl    $$4,rINST                       # rINST <- B
%   if wide:
      GET_WIDE_VREG %rax, rINSTq            # rax <- vB
%   else:
      GET_VREG %eax, rINSTq                 # eax <- vB
    andb    $$0xf,%cl                       # ecx <- A
    $preinstr
    $instr
%   if wide:
      SET_WIDE_VREG %rax, %rcx
%   else:
      SET_VREG %eax, %rcx
    ADVANCE_PC_FETCH_AND_GOTO_NEXT 1

%def op_add_int():
%  binop(instr="addl")

%def op_add_int_2addr():
%  binop2addr(instr="addl")

%def op_add_int_lit16():
%  binopLit16(instr="addl    %ecx, %eax")

%def op_add_int_lit8():
%  binopLit8(instr="addl    %ecx, %eax")

%def op_add_long():
%  binopWide(instr="addq")

%def op_add_long_2addr():
%  binopWide2addr(instr="addq")

%def op_and_int():
%  binop(instr="andl")

%def op_and_int_2addr():
%  binop2addr(instr="andl")

%def op_and_int_lit16():
%  binopLit16(instr="andl    %ecx, %eax")

%def op_and_int_lit8():
%  binopLit8(instr="andl    %ecx, %eax")

%def op_and_long():
%  binopWide(instr="andq")

%def op_and_long_2addr():
%  binopWide2addr(instr="andq")

%def op_cmp_long():
/*
 * Compare two 64-bit values.  Puts 0, 1, or -1 into the destination
 * register based on the results of the comparison.
 */

    /* cmp-long vAA, vBB, vCC */
    movzbq  2(rPC), %rdx                    # edx <- BB
    movzbq  3(rPC), %rcx                    # ecx <- CC
    GET_WIDE_VREG %rdx, %rdx                # rdx <- v[BB]
    xorl    %eax, %eax
    xorl    %edi, %edi
    addb    $$1, %al
    movl    $$-1, %esi
    cmpq    VREG_ADDRESS(%rcx), %rdx
    cmovl   %esi, %edi
    cmovg   %eax, %edi
    SET_VREG %edi, rINSTq
    ADVANCE_PC_FETCH_AND_GOTO_NEXT 2

%def op_div_int():
%  bindiv(result="%eax", second="%ecx", tmp="%edx", suffix="l")

%def op_div_int_2addr():
%  bindiv2addr(result="%eax", second="%ecx", tmp="%edx", suffix="l")

%def op_div_int_lit16():
%  bindivLit16(result="%eax")

%def op_div_int_lit8():
%  bindivLit8(result="%eax")

%def op_div_long():
%  bindiv(result="%rax", second="%rcx", tmp="%rdx", wide=True, suffix="q", ext="cqo")

%def op_div_long_2addr():
%  bindiv2addr(result="%rax", second="%rcx", tmp="%rdx", wide=True, suffix="q", ext="cqo")

%def op_int_to_byte():
%  unop(instr="movsbl  %al, %eax")

%def op_int_to_char():
%  unop(instr="movzwl  %ax,%eax")

%def op_int_to_long():
    /* int to long vA, vB */
    movzbq  rINSTbl, %rax                   # rax <- +A
    sarl    $$4, %eax                       # eax <- B
    andb    $$0xf, rINSTbl                  # rINST <- A
    movslq  VREG_ADDRESS(%rax), %rax
    SET_WIDE_VREG %rax, rINSTq              # v[A] <- %rax
    ADVANCE_PC_FETCH_AND_GOTO_NEXT 1


%def op_int_to_short():
%  unop(instr="movswl %ax, %eax")

%def op_long_to_int():
/* we ignore the high word, making this equivalent to a 32-bit reg move */
%  op_move()

%def op_mul_int():
%  binop(instr="imull")

%def op_mul_int_2addr():
    /* mul vA, vB */
    movl    rINST, %ecx                     # rcx <- A+
    sarl    $$4, rINST                      # rINST <- B
    andb    $$0xf, %cl                      # ecx <- A
    GET_VREG %eax, %rcx                     # eax <- vA
    imull   (rFP,rINSTq,4), %eax
    SET_VREG %eax, %rcx
    ADVANCE_PC_FETCH_AND_GOTO_NEXT 1

%def op_mul_int_lit16():
%  binopLit16(instr="imull   %ecx, %eax")

%def op_mul_int_lit8():
%  binopLit8(instr="imull   %ecx, %eax")

%def op_mul_long():
%  binopWide(instr="imulq")

%def op_mul_long_2addr():
    /* mul vA, vB */
    movl    rINST, %ecx                     # rcx <- A+
    sarl    $$4, rINST                      # rINST <- B
    andb    $$0xf, %cl                      # ecx <- A
    GET_WIDE_VREG %rax, %rcx                # rax <- vA
    imulq   (rFP,rINSTq,4), %rax
    SET_WIDE_VREG %rax, %rcx
    ADVANCE_PC_FETCH_AND_GOTO_NEXT 1

%def op_neg_int():
%  unop(instr="    negl    %eax")

%def op_neg_long():
%  unop(instr="    negq    %rax", wide=True)

%def op_not_int():
%  unop(instr="    notl    %eax")

%def op_not_long():
%  unop(instr="    notq    %rax", wide=True)

%def op_or_int():
%  binop(instr="orl")

%def op_or_int_2addr():
%  binop2addr(instr="orl")

%def op_or_int_lit16():
%  binopLit16(instr="orl     %ecx, %eax")

%def op_or_int_lit8():
%  binopLit8(instr="orl     %ecx, %eax")

%def op_or_long():
%  binopWide(instr="orq")

%def op_or_long_2addr():
%  binopWide2addr(instr="orq")

%def op_rem_int():
%  bindiv(result="%edx", second="%ecx", tmp="%eax", suffix="l", rem=True)

%def op_rem_int_2addr():
%  bindiv2addr(result="%edx", second="%ecx", tmp="%eax", suffix="l", rem=True)

%def op_rem_int_lit16():
%  bindivLit16(result="%edx", rem=True)

%def op_rem_int_lit8():
%  bindivLit8(result="%edx", rem=True)

%def op_rem_long():
%  bindiv(result="%rdx", second="%rcx", tmp="%rax", wide=True, suffix="q", ext="cqo", rem=True)

%def op_rem_long_2addr():
%  bindiv2addr(result="%rdx", second="%rcx", tmp="%rax", wide=True, suffix="q", rem=True, ext="cqo")

%def op_rsub_int():
/* this op is "rsub-int", but can be thought of as "rsub-int/lit16" */
%  binopLit16(instr="subl    %eax, %ecx", result="%ecx")

%def op_rsub_int_lit8():
%  binopLit8(instr="subl    %eax, %ecx", result="%ecx")

%def op_shl_int():
%  binop1(instr="sall    %cl, %eax")

%def op_shl_int_2addr():
%  shop2addr(instr="sall    %cl, %eax")

%def op_shl_int_lit8():
%  binopLit8(instr="sall    %cl, %eax")

%def op_shl_long():
%  binop1(instr="salq    %cl, %rax", wide=True)

%def op_shl_long_2addr():
%  shop2addr(instr="salq    %cl, %rax", wide=True)

%def op_shr_int():
%  binop1(instr="sarl    %cl, %eax")

%def op_shr_int_2addr():
%  shop2addr(instr="sarl    %cl, %eax")

%def op_shr_int_lit8():
%  binopLit8(instr="sarl    %cl, %eax")

%def op_shr_long():
%  binop1(instr="sarq    %cl, %rax", wide=True)

%def op_shr_long_2addr():
%  shop2addr(instr="sarq    %cl, %rax", wide=True)

%def op_sub_int():
%  binop(instr="subl")

%def op_sub_int_2addr():
%  binop2addr(instr="subl")

%def op_sub_long():
%  binopWide(instr="subq")

%def op_sub_long_2addr():
%  binopWide2addr(instr="subq")

%def op_ushr_int():
%  binop1(instr="shrl    %cl, %eax")

%def op_ushr_int_2addr():
%  shop2addr(instr="shrl    %cl, %eax")

%def op_ushr_int_lit8():
%  binopLit8(instr="shrl    %cl, %eax")

%def op_ushr_long():
%  binop1(instr="shrq    %cl, %rax", wide=True)

%def op_ushr_long_2addr():
%  shop2addr(instr="shrq    %cl, %rax", wide=True)

%def op_xor_int():
%  binop(instr="xorl")

%def op_xor_int_2addr():
%  binop2addr(instr="xorl")

%def op_xor_int_lit16():
%  binopLit16(instr="xorl    %ecx, %eax")

%def op_xor_int_lit8():
%  binopLit8(instr="xorl    %ecx, %eax")

%def op_xor_long():
%  binopWide(instr="xorq")

%def op_xor_long_2addr():
%  binopWide2addr(instr="xorq")

Messung V0.5 in Prozent
C=92 H=92 G=91

¤ Dauer der Verarbeitung: 0.2 Sekunden  (vorverarbeitet am  2026-06-29) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.