*** empty log message ***
From-SVN: r328
This commit is contained in:
parent
00fe048c3c
commit
2bb7a0f55b
@ -206,6 +206,9 @@
|
||||
"TARGET_80387"
|
||||
"")
|
||||
|
||||
;; The `ble' and `blt' patterns can reverse a compare, so we must allow
|
||||
;; an immediate operand as operand 0 in the recognizers below.
|
||||
|
||||
(define_insn ""
|
||||
[(set (cc0)
|
||||
(compare (match_operand:DF 0 "general_operand" "f")
|
||||
@ -356,9 +359,24 @@
|
||||
|
||||
;; General case of fullword move.
|
||||
|
||||
;; If generating PIC code and operands[1] is a symbolic CONST, emit a
|
||||
;; move to get the address of the symbolic object from the GOT.
|
||||
|
||||
(define_expand "movsi"
|
||||
[(set (match_operand:SI 0 "general_operand" "")
|
||||
(match_operand:SI 1 "general_operand" ""))]
|
||||
""
|
||||
"
|
||||
{
|
||||
extern int flag_pic;
|
||||
|
||||
if (flag_pic && SYMBOLIC_CONST (operands[1]))
|
||||
emit_pic_move (operands, SImode);
|
||||
}")
|
||||
|
||||
;; On i486, incl reg is faster than movl $1,reg.
|
||||
|
||||
(define_insn "movsi"
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "general_operand" "=g,r")
|
||||
(match_operand:SI 1 "general_operand" "ri,m"))]
|
||||
""
|
||||
@ -1490,10 +1508,10 @@
|
||||
;; Remainder instructions.
|
||||
|
||||
(define_insn "divmodsi4"
|
||||
[(set (match_operand:SI 0 "general_operand" "=a")
|
||||
(div:SI (match_operand:SI 1 "general_operand" "0")
|
||||
[(set (match_operand:SI 0 "register_operand" "=a")
|
||||
(div:SI (match_operand:SI 1 "register_operand" "0")
|
||||
(match_operand:SI 2 "general_operand" "rm")))
|
||||
(set (match_operand:SI 3 "general_operand" "=&d")
|
||||
(set (match_operand:SI 3 "register_operand" "=&d")
|
||||
(mod:SI (match_dup 1) (match_dup 2)))]
|
||||
""
|
||||
"*
|
||||
@ -1507,20 +1525,20 @@
|
||||
}")
|
||||
|
||||
(define_insn "divmodhi4"
|
||||
[(set (match_operand:HI 0 "general_operand" "=a")
|
||||
(div:HI (match_operand:HI 1 "general_operand" "0")
|
||||
[(set (match_operand:HI 0 "register_operand" "=a")
|
||||
(div:HI (match_operand:HI 1 "register_operand" "0")
|
||||
(match_operand:HI 2 "general_operand" "rm")))
|
||||
(set (match_operand:HI 3 "general_operand" "=&d")
|
||||
(set (match_operand:HI 3 "register_operand" "=&d")
|
||||
(mod:HI (match_dup 1) (match_dup 2)))]
|
||||
""
|
||||
"cwtd\;idiv%W0 %2")
|
||||
|
||||
;; ??? Can we make gcc zero extend operand[0]?
|
||||
(define_insn "udivmodsi4"
|
||||
[(set (match_operand:SI 0 "general_operand" "=a")
|
||||
(udiv:SI (match_operand:SI 1 "general_operand" "0")
|
||||
[(set (match_operand:SI 0 "register_operand" "=a")
|
||||
(udiv:SI (match_operand:SI 1 "register_operand" "0")
|
||||
(match_operand:SI 2 "general_operand" "rm")))
|
||||
(set (match_operand:SI 3 "general_operand" "=&d")
|
||||
(set (match_operand:SI 3 "register_operand" "=&d")
|
||||
(umod:SI (match_dup 1) (match_dup 2)))]
|
||||
""
|
||||
"*
|
||||
@ -1531,10 +1549,10 @@
|
||||
|
||||
;; ??? Can we make gcc zero extend operand[0]?
|
||||
(define_insn "udivmodhi4"
|
||||
[(set (match_operand:HI 0 "general_operand" "=a")
|
||||
(udiv:HI (match_operand:HI 1 "general_operand" "0")
|
||||
[(set (match_operand:HI 0 "register_operand" "=a")
|
||||
(udiv:HI (match_operand:HI 1 "register_operand" "0")
|
||||
(match_operand:HI 2 "general_operand" "rm")))
|
||||
(set (match_operand:HI 3 "general_operand" "=&d")
|
||||
(set (match_operand:HI 3 "register_operand" "=&d")
|
||||
(umod:HI (match_dup 1) (match_dup 2)))]
|
||||
""
|
||||
"*
|
||||
@ -1547,10 +1565,10 @@
|
||||
;;this should be a valid double division which we may want to add
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "general_operand" "=a")
|
||||
(udiv:DI (match_operand:DI 1 "general_operand" "a")
|
||||
(match_operand:SI 2 "general_operand" "rm")))
|
||||
(set (match_operand:SI 3 "general_operand" "=d")
|
||||
[(set (match_operand:SI 0 "register_operand" "=a")
|
||||
(udiv:DI (match_operand:DI 1 "register_operand" "a")
|
||||
(match_operand:SI 2 "general_operand" "rm")))
|
||||
(set (match_operand:SI 3 "register_operand" "=d")
|
||||
(umod:SI (match_dup 1) (match_dup 2)))]
|
||||
""
|
||||
"div%L0 %2,%0")
|
||||
@ -2605,7 +2623,7 @@
|
||||
;; bt on the MEM directly.
|
||||
|
||||
(define_insn ""
|
||||
[(set (cc0) (zero_extract (match_operand:QI 0 "nonimmediate_operand" "q")
|
||||
[(set (cc0) (zero_extract (match_operand:QI 0 "register_operand" "q")
|
||||
(const_int 1)
|
||||
(match_operand:SI 1 "general_operand" "ri")))]
|
||||
""
|
||||
@ -2625,6 +2643,34 @@
|
||||
RET;
|
||||
}")
|
||||
|
||||
(define_insn ""
|
||||
[(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "m")
|
||||
(const_int 1)
|
||||
(match_operand:SI 1 "general_operand" "ri")))
|
||||
(clobber (match_scratch:SI 2 "=&r"))]
|
||||
""
|
||||
"*
|
||||
{
|
||||
/* Copy memory to scratch register; pretend it was there to start with. */
|
||||
if (GET_CODE (operands[0]) == MEM)
|
||||
{
|
||||
output_asm_insn (AS2 (mov%L2,%0,%2), operands);
|
||||
operands[0] = operands[2];
|
||||
}
|
||||
if (GET_CODE (operands[1]) == CONST_INT)
|
||||
{
|
||||
operands[1] = gen_rtx (CONST_INT, VOIDmode, 1 << INTVAL (operands[1]));
|
||||
output_asm_insn (AS2 (test%L0,%1,%0), operands);
|
||||
}
|
||||
else
|
||||
{
|
||||
operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]));
|
||||
cc_status.flags |= CC_Z_IN_NOT_C;
|
||||
output_asm_insn (AS2 (bt%L0,%1,%0), operands);
|
||||
}
|
||||
RET;
|
||||
}")
|
||||
|
||||
(define_insn ""
|
||||
[(set (cc0) (zero_extract (match_operand:HI 0 "nonimmediate_operand" "r")
|
||||
(const_int 1)
|
||||
@ -2673,7 +2719,7 @@
|
||||
""
|
||||
"*
|
||||
{
|
||||
if (cc_status.flags & CC_Z_IN_NOT_C)
|
||||
if (cc_prev_status.flags & CC_Z_IN_NOT_C)
|
||||
return AS1 (setnb,%0);
|
||||
else
|
||||
return AS1 (sete,%0);
|
||||
@ -2686,7 +2732,7 @@
|
||||
""
|
||||
"*
|
||||
{
|
||||
if (cc_status.flags & CC_Z_IN_NOT_C)
|
||||
if (cc_prev_status.flags & CC_Z_IN_NOT_C)
|
||||
return AS1 (setb,%0);
|
||||
else
|
||||
return AS1 (setne,%0);
|
||||
@ -2753,7 +2799,7 @@
|
||||
""
|
||||
"*
|
||||
{
|
||||
if (cc_status.flags & CC_Z_IN_NOT_C)
|
||||
if (cc_prev_status.flags & CC_Z_IN_NOT_C)
|
||||
return \"jnc %l0\";
|
||||
else
|
||||
return \"je %l0\";
|
||||
@ -2768,7 +2814,7 @@
|
||||
""
|
||||
"*
|
||||
{
|
||||
if (cc_status.flags & CC_Z_IN_NOT_C)
|
||||
if (cc_prev_status.flags & CC_Z_IN_NOT_C)
|
||||
return \"jc %l0\";
|
||||
else
|
||||
return \"jne %l0\";
|
||||
@ -2915,7 +2961,7 @@
|
||||
""
|
||||
"*
|
||||
{
|
||||
if (cc_status.flags & CC_Z_IN_NOT_C)
|
||||
if (cc_prev_status.flags & CC_Z_IN_NOT_C)
|
||||
return \"jc %l0\";
|
||||
else
|
||||
return \"jne %l0\";
|
||||
@ -2930,7 +2976,7 @@
|
||||
""
|
||||
"*
|
||||
{
|
||||
if (cc_status.flags & CC_Z_IN_NOT_C)
|
||||
if (cc_prev_status.flags & CC_Z_IN_NOT_C)
|
||||
return \"jnc %l0\";
|
||||
else
|
||||
return \"je %l0\";
|
||||
@ -3018,7 +3064,7 @@
|
||||
"jmp %l0")
|
||||
|
||||
(define_insn "indirect_jump"
|
||||
[(set (pc) (match_operand:SI 0 "register_operand" "a"))]
|
||||
[(set (pc) (match_operand:SI 0 "general_operand" "rm"))]
|
||||
""
|
||||
"*
|
||||
{
|
||||
@ -3027,6 +3073,98 @@
|
||||
return AS1 (jmp,%*%0);
|
||||
}")
|
||||
|
||||
;; Implement switch statements when generating PIC code. Switches are
|
||||
;; implemented by `tablejump' when not using -fpic.
|
||||
|
||||
;; Emit code here to do the range checking and make the index zero based.
|
||||
|
||||
(define_expand "casesi"
|
||||
[(parallel
|
||||
[(set (pc)
|
||||
(if_then_else (leu (minus:SI
|
||||
(match_operand:SI 0 "general_operand" "")
|
||||
(match_operand:SI 1 "const_int_operand" ""))
|
||||
(match_operand:SI 2 "const_int_operand" ""))
|
||||
(plus:SI (mem:SI (plus:SI (pc)
|
||||
(minus:SI (match_dup 0)
|
||||
(match_dup 1))))
|
||||
(label_ref (match_operand 3 "" "")))
|
||||
(pc)))
|
||||
(use (label_ref (match_operand 4 "" "")))
|
||||
(clobber (match_scratch:SI 5 ""))])]
|
||||
"flag_pic"
|
||||
"
|
||||
{
|
||||
rtx reg = gen_reg_rtx (SImode);
|
||||
|
||||
current_function_uses_pic_offset_table = 1;
|
||||
|
||||
emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
|
||||
emit_insn (gen_cmpsi (reg, operands[2]));
|
||||
emit_jump_insn (gen_bgtu (operands[4]));
|
||||
operands[0] = reg;
|
||||
operands[1] = CONST0_RTX (SImode);
|
||||
}")
|
||||
|
||||
;; Implement a casesi insn.
|
||||
|
||||
;; Each entry in the "addr_diff_vec" looks like this as the result of the
|
||||
;; two rules below:
|
||||
;;
|
||||
;; .long _GLOBAL_OFFSET_TABLE_+[.-.L2]
|
||||
;;
|
||||
;; 1. An expression involving an external reference may only use the
|
||||
;; addition operator, and only with an assembly-time constant.
|
||||
;; The example above satisfies this because ".-.L2" is a constant.
|
||||
;;
|
||||
;; 2. The symbol _GLOBAL_OFFSET_TABLE_ is magic, and at link time is
|
||||
;; given the value of "GOT - .", where GOT is the actual address of
|
||||
;; the Global Offset Table. Therefore, the .long above actually
|
||||
;; stores the value "( GOT - . ) + [ . - .L2 ]", or "GOT - .L2". The
|
||||
;; expression "GOT - .L2" by itself would generate an error from as(1).
|
||||
;;
|
||||
;; The pattern below emits code that looks like this:
|
||||
;;
|
||||
;; movl %ebx,reg
|
||||
;; subl TABLE@GOTOFF(%ebx,index,4),reg
|
||||
;; jmp reg
|
||||
;;
|
||||
;; The addr_diff_vec contents may be directly referenced with @GOTOFF, since
|
||||
;; the addr_diff_vec is known to be part of this module.
|
||||
;;
|
||||
;; The subl above calculates "GOT - (( GOT - . ) + [ . - .L2 ])", which
|
||||
;; evaluates to just ".L2".
|
||||
|
||||
(define_insn ""
|
||||
[(set (pc)
|
||||
(if_then_else (leu (minus:SI
|
||||
(match_operand:SI 0 "general_operand" "r")
|
||||
(match_operand:SI 1 "const_int_operand" "i"))
|
||||
(match_operand:SI 2 "const_int_operand" "i"))
|
||||
(plus:SI (mem:SI (plus:SI (pc)
|
||||
(minus:SI (match_dup 0)
|
||||
(match_dup 1))))
|
||||
(label_ref (match_operand 3 "" "")))
|
||||
(pc)))
|
||||
(use (label_ref (match_operand 4 "" "")))
|
||||
(clobber (match_scratch:SI 5 "=&r"))]
|
||||
""
|
||||
"*
|
||||
{
|
||||
rtx xops[4];
|
||||
|
||||
xops[0] = pic_offset_table_rtx;
|
||||
xops[1] = operands[5];
|
||||
xops[2] = operands[3];
|
||||
xops[3] = operands[0];
|
||||
|
||||
output_asm_insn (AS2 (mov%L1,%0,%1), xops);
|
||||
output_asm_insn (\"sub%L1 %l2@GOTOFF(%0,%3,4),%1\", xops);
|
||||
output_asm_insn (AS1 (jmp,%*%1), xops);
|
||||
ASM_OUTPUT_ALIGN_CODE (asm_out_file);
|
||||
RET;
|
||||
}")
|
||||
|
||||
(define_insn "tablejump"
|
||||
[(set (pc) (match_operand:SI 0 "general_operand" "rm"))
|
||||
(use (label_ref (match_operand 1 "" "")))]
|
||||
@ -3038,9 +3176,31 @@
|
||||
return AS1 (jmp,%*%0);
|
||||
}")
|
||||
|
||||
;; Call insns.
|
||||
|
||||
;; If generating PIC code, the predicate indirect_operand will fail
|
||||
;; for operands[0] containing symbolic references on all of the named
|
||||
;; call* patterns. Each named pattern is followed by an unnamed pattern
|
||||
;; that matches any call to a symbolic CONST (ie, a symbol_ref). The
|
||||
;; unnamed patterns are only used while generating PIC code, because
|
||||
;; otherwise the named patterns match.
|
||||
|
||||
;; Call subroutine returning no value.
|
||||
|
||||
(define_insn "call_pop"
|
||||
(define_expand "call_pop"
|
||||
[(parallel [(call (match_operand:QI 0 "indirect_operand" "")
|
||||
(match_operand:SI 1 "general_operand" ""))
|
||||
(set (reg:SI 7)
|
||||
(plus:SI (reg:SI 7)
|
||||
(match_operand:SI 3 "immediate_operand" "")))])]
|
||||
""
|
||||
"
|
||||
{
|
||||
if (flag_pic)
|
||||
current_function_uses_pic_offset_table = 1;
|
||||
}")
|
||||
|
||||
(define_insn ""
|
||||
[(call (match_operand:QI 0 "indirect_operand" "m")
|
||||
(match_operand:SI 1 "general_operand" "g"))
|
||||
(set (reg:SI 7) (plus:SI (reg:SI 7)
|
||||
@ -3058,7 +3218,26 @@
|
||||
return AS1 (call,%P0);
|
||||
}")
|
||||
|
||||
(define_insn "call"
|
||||
(define_insn ""
|
||||
[(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
|
||||
(match_operand:SI 1 "general_operand" "g"))
|
||||
(set (reg:SI 7) (plus:SI (reg:SI 7)
|
||||
(match_operand:SI 3 "immediate_operand" "i")))]
|
||||
""
|
||||
"call %P0")
|
||||
|
||||
(define_expand "call"
|
||||
[(call (match_operand:QI 0 "indirect_operand" "")
|
||||
(match_operand:SI 1 "general_operand" ""))]
|
||||
;; Operand 1 not used on the i386.
|
||||
""
|
||||
"
|
||||
{
|
||||
if (flag_pic)
|
||||
current_function_uses_pic_offset_table = 1;
|
||||
}")
|
||||
|
||||
(define_insn ""
|
||||
[(call (match_operand:QI 0 "indirect_operand" "m")
|
||||
(match_operand:SI 1 "general_operand" "g"))]
|
||||
;; Operand 1 not used on the i386.
|
||||
@ -3075,10 +3254,31 @@
|
||||
return AS1 (call,%P0);
|
||||
}")
|
||||
|
||||
(define_insn ""
|
||||
[(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
|
||||
(match_operand:SI 1 "general_operand" "g"))]
|
||||
;; Operand 1 not used on the i386.
|
||||
""
|
||||
"call %P0")
|
||||
|
||||
;; Call subroutine, returning value in operand 0
|
||||
;; (which must be a hard register).
|
||||
|
||||
(define_insn "call_value_pop"
|
||||
(define_expand "call_value_pop"
|
||||
[(parallel [(set (match_operand 0 "" "")
|
||||
(call (match_operand:QI 1 "indirect_operand" "")
|
||||
(match_operand:SI 2 "general_operand" "")))
|
||||
(set (reg:SI 7)
|
||||
(plus:SI (reg:SI 7)
|
||||
(match_operand:SI 4 "immediate_operand" "")))])]
|
||||
""
|
||||
"
|
||||
{
|
||||
if (flag_pic)
|
||||
current_function_uses_pic_offset_table = 1;
|
||||
}")
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand 0 "" "=rf")
|
||||
(call (match_operand:QI 1 "indirect_operand" "m")
|
||||
(match_operand:SI 2 "general_operand" "g")))
|
||||
@ -3099,7 +3299,28 @@
|
||||
RET;
|
||||
}")
|
||||
|
||||
(define_insn "call_value"
|
||||
(define_insn ""
|
||||
[(set (match_operand 0 "" "=rf")
|
||||
(call (mem:QI (match_operand:SI 1 "symbolic_operand" ""))
|
||||
(match_operand:SI 2 "general_operand" "g")))
|
||||
(set (reg:SI 7) (plus:SI (reg:SI 7)
|
||||
(match_operand:SI 4 "immediate_operand" "i")))]
|
||||
""
|
||||
"call %P1")
|
||||
|
||||
(define_expand "call_value"
|
||||
[(set (match_operand 0 "" "")
|
||||
(call (match_operand:QI 1 "indirect_operand" "")
|
||||
(match_operand:SI 2 "general_operand" "")))]
|
||||
;; Operand 2 not used on the i386.
|
||||
""
|
||||
"
|
||||
{
|
||||
if (flag_pic)
|
||||
current_function_uses_pic_offset_table = 1;
|
||||
}")
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand 0 "" "=rf")
|
||||
(call (match_operand:QI 1 "indirect_operand" "m")
|
||||
(match_operand:SI 2 "general_operand" "g")))]
|
||||
@ -3119,6 +3340,14 @@
|
||||
RET;
|
||||
}")
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand 0 "" "=rf")
|
||||
(call (mem:QI (match_operand:SI 1 "symbolic_operand" ""))
|
||||
(match_operand:SI 2 "general_operand" "g")))]
|
||||
;; Operand 2 not used on the i386.
|
||||
""
|
||||
"call %P1")
|
||||
|
||||
;; Insn emitted into the body of a function to return from a function.
|
||||
;; This is only done if the function's epilogue is known to be simple.
|
||||
;; See comments for simple_386_epilogue in i386.c.
|
||||
|
Loading…
Reference in New Issue
Block a user