m68hc11.c (m68hc11_symbolic_p): New function.
* config/m68hc11/m68hc11.c (m68hc11_symbolic_p): New function. (m68hc11_indirect_p): New function. (m68hc11_override_options): Must set MASK_NO_DIRECT_MODE for 68HC12. (m68hc11_gen_highpart): Use TARGET_NO_DIRECT_MODE instead of TARGET_M6812. (asm_print_register): Likewise. * config/m68hc11/m68hc11-protos.h (m68hc11_symbolic_p): Declare. (m68hc11_indirect_p): Declare. * config/m68hc11/m68hc11.h (EXTRA_CONSTRAINT): New constraint 'R', 'Q'. (TARGET_NO_DIRECT_MODE, TARGET_RELAX): New. (TARGET_SWITCHES): New option -mrelax. * config/m68hc11/m68hc11.md ("andsi3"): Allow soft register for destination. ("iorsi3", "xorsi3"): Likewise. ("andhi3", "andqi3", "iorhi3", "iorqi3"): Use a define_expand. ("*andhi3_mem"): New to handle destination in memory with bclr and a scratch register. ("*andqi3_mem", "*iorhi3_mem", "*iorqi3_mem"): Likewise. ("*andhi3_const"): New when operand2 is constant. ("*andqi3_const", "*iorhi3_const", "*iorqi3_const"): Likewise. ("*andhi3_gen"): Cleanup of the old "andhi3". ("*andqi3_gen", "*iorhi3_gen", "*iorqi3_gen"): Likewise. ("xorqi3"): Update constraints. From-SVN: r50843
This commit is contained in:
parent
60f32585da
commit
932657df23
@ -1,3 +1,29 @@
|
||||
2002-03-15 Stephane Carrez <Stephane.Carrez@worldnet.fr>
|
||||
|
||||
* config/m68hc11/m68hc11.c (m68hc11_symbolic_p): New function.
|
||||
(m68hc11_indirect_p): New function.
|
||||
(m68hc11_override_options): Must set MASK_NO_DIRECT_MODE for 68HC12.
|
||||
(m68hc11_gen_highpart): Use TARGET_NO_DIRECT_MODE instead of
|
||||
TARGET_M6812.
|
||||
(asm_print_register): Likewise.
|
||||
* config/m68hc11/m68hc11-protos.h (m68hc11_symbolic_p): Declare.
|
||||
(m68hc11_indirect_p): Declare.
|
||||
* config/m68hc11/m68hc11.h (EXTRA_CONSTRAINT): New constraint 'R', 'Q'.
|
||||
(TARGET_NO_DIRECT_MODE, TARGET_RELAX): New.
|
||||
(TARGET_SWITCHES): New option -mrelax.
|
||||
* config/m68hc11/m68hc11.md ("andsi3"): Allow soft register for
|
||||
destination.
|
||||
("iorsi3", "xorsi3"): Likewise.
|
||||
("andhi3", "andqi3", "iorhi3", "iorqi3"): Use a define_expand.
|
||||
("*andhi3_mem"): New to handle destination in memory with bclr
|
||||
and a scratch register.
|
||||
("*andqi3_mem", "*iorhi3_mem", "*iorqi3_mem"): Likewise.
|
||||
("*andhi3_const"): New when operand2 is constant.
|
||||
("*andqi3_const", "*iorhi3_const", "*iorqi3_const"): Likewise.
|
||||
("*andhi3_gen"): Cleanup of the old "andhi3".
|
||||
("*andqi3_gen", "*iorhi3_gen", "*iorqi3_gen"): Likewise.
|
||||
("xorqi3"): Update constraints.
|
||||
|
||||
2002-03-15 Stephane Carrez <Stephane.Carrez@worldnet.fr>
|
||||
|
||||
* config/m68hc11/m68hc11.c (m68hc11_small_indexed_indirect_p): Look
|
||||
|
@ -106,6 +106,8 @@ extern void m68hc11_emit_libcall PARAMS((const char*, enum rtx_code,
|
||||
enum machine_mode, enum machine_mode,
|
||||
int, rtx*));
|
||||
extern int m68hc11_small_indexed_indirect_p PARAMS((rtx, enum machine_mode));
|
||||
extern int m68hc11_symbolic_p PARAMS((rtx, enum machine_mode));
|
||||
extern int m68hc11_indirect_p PARAMS((rtx, enum machine_mode));
|
||||
extern int go_if_legitimate_address2 PARAMS((rtx, enum machine_mode, int));
|
||||
|
||||
extern int reg_or_indexed_operand PARAMS((rtx,enum machine_mode));
|
||||
|
@ -276,6 +276,7 @@ m68hc11_override_options ()
|
||||
m68hc11_sp_correction = 0;
|
||||
m68hc11_tmp_regs_class = TMP_REGS;
|
||||
target_flags &= ~MASK_M6811;
|
||||
target_flags |= MASK_NO_DIRECT_MODE;
|
||||
if (m68hc11_soft_reg_count == 0)
|
||||
m68hc11_soft_reg_count = "2";
|
||||
}
|
||||
@ -926,6 +927,42 @@ reg_or_some_mem_operand (operand, mode)
|
||||
return register_operand (operand, mode);
|
||||
}
|
||||
|
||||
int
|
||||
m68hc11_symbolic_p (operand, mode)
|
||||
rtx operand;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
if (GET_CODE (operand) == MEM)
|
||||
{
|
||||
rtx op = XEXP (operand, 0);
|
||||
|
||||
if (symbolic_memory_operand (op, mode))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
m68hc11_indirect_p (operand, mode)
|
||||
rtx operand;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
if (GET_CODE (operand) == MEM)
|
||||
{
|
||||
rtx op = XEXP (operand, 0);
|
||||
|
||||
if (symbolic_memory_operand (op, mode))
|
||||
return 0;
|
||||
|
||||
if (reload_in_progress)
|
||||
return 1;
|
||||
|
||||
operand = XEXP (operand, 0);
|
||||
return register_indirect_p (operand, mode, reload_completed);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
stack_register_operand (operand, mode)
|
||||
rtx operand;
|
||||
@ -1950,8 +1987,9 @@ m68hc11_gen_highpart (mode, x)
|
||||
{
|
||||
int pos;
|
||||
|
||||
/* For 68HC12, avoid the '*' for direct addressing mode. */
|
||||
pos = TARGET_M6812 ? 1 : 0;
|
||||
/* Avoid the '*' for direct addressing mode when this
|
||||
addressing mode is disabled. */
|
||||
pos = TARGET_NO_DIRECT_MODE ? 1 : 0;
|
||||
return gen_rtx (MEM, QImode,
|
||||
gen_rtx (SYMBOL_REF, Pmode,
|
||||
®_names[REGNO (x)][pos]));
|
||||
@ -2079,7 +2117,7 @@ asm_print_register (file, regno)
|
||||
{
|
||||
const char *name = reg_names[regno];
|
||||
|
||||
if (TARGET_M6812 && name[0] == '*')
|
||||
if (TARGET_NO_DIRECT_MODE && name[0] == '*')
|
||||
name++;
|
||||
|
||||
asm_fprintf (file, "%s", name);
|
||||
|
@ -118,12 +118,15 @@ extern short *reg_renumber; /* def in local_alloc.c */
|
||||
#define MASK_AUTO_INC_DEC 0004
|
||||
#define MASK_M6811 0010
|
||||
#define MASK_M6812 0020
|
||||
#define MASK_NO_DIRECT_MODE 0040
|
||||
|
||||
#define TARGET_OP_TIME (optimize && optimize_size == 0)
|
||||
#define TARGET_SHORT (target_flags & MASK_SHORT)
|
||||
#define TARGET_M6811 (target_flags & MASK_M6811)
|
||||
#define TARGET_M6812 (target_flags & MASK_M6812)
|
||||
#define TARGET_AUTO_INC_DEC (target_flags & MASK_AUTO_INC_DEC)
|
||||
#define TARGET_NO_DIRECT_MODE (target_flags & MASK_NO_DIRECT_MODE)
|
||||
#define TARGET_RELAX (TARGET_NO_DIRECT_MODE)
|
||||
|
||||
/* Default target_flags if no switches specified. */
|
||||
#ifndef TARGET_DEFAULT
|
||||
@ -156,6 +159,8 @@ extern short *reg_renumber; /* def in local_alloc.c */
|
||||
N_("Auto pre/post decrement increment allowed")}, \
|
||||
{ "noauto-incdec", - MASK_AUTO_INC_DEC, \
|
||||
N_("Auto pre/post decrement increment not allowed")}, \
|
||||
{ "relax", MASK_NO_DIRECT_MODE, \
|
||||
N_("Do not use direct addressing mode for soft registers")},\
|
||||
{ "68hc11", MASK_M6811, \
|
||||
N_("Compile for a 68HC11")}, \
|
||||
{ "68hc12", MASK_M6812, \
|
||||
@ -830,7 +835,9 @@ extern enum reg_class m68hc11_tmp_regs_class;
|
||||
/* 'U' represents certain kind of memory indexed operand for 68HC12.
|
||||
and any memory operand for 68HC11. */
|
||||
#define EXTRA_CONSTRAINT(OP, C) \
|
||||
((C) == 'U' ? m68hc11_small_indexed_indirect_p (OP, GET_MODE (OP)) : 0)
|
||||
((C) == 'U' ? m68hc11_small_indexed_indirect_p (OP, GET_MODE (OP)) \
|
||||
: (C) == 'Q' ? m68hc11_symbolic_p (OP, GET_MODE (OP)) \
|
||||
: (C) == 'R' ? m68hc11_indirect_p (OP, GET_MODE (OP)) : 0)
|
||||
|
||||
|
||||
|
||||
|
@ -65,9 +65,20 @@
|
||||
;;
|
||||
;; Other constraints:
|
||||
;;
|
||||
;; T an operand that can be accessed with 68HC1X direct addressing
|
||||
;; mode. For 68HC11 this includes the pseudo soft registers and
|
||||
;; any memory operand that is a direct addressing (.page0).
|
||||
;; Q an operand which is in memory but whose address is constant
|
||||
;; (ie, a (MEM (SYMBOL_REF x))). This constraint is used by
|
||||
;; bset/bclr instructions together with linker relaxation. The
|
||||
;; operand can be translated to a page0 addressing mode if the
|
||||
;; symbol address is in page0 (0..255).
|
||||
;;
|
||||
;; R an operand which is in memory and whose address is expressed
|
||||
;; with 68HC11/68HC12 indexed addressing mode. In general this
|
||||
;; is any valid (MEM) except a (MEM (SYMBOL_REF x)).
|
||||
;;
|
||||
;; U an operand which is in memory and if it uses the 68HC12 indexed
|
||||
;; addressing mode, the offset is in the range -16..+15. This is
|
||||
;; used by 68HC12 movb/movw instructions since they do not accept
|
||||
;; the full 16-bit offset range (as other insn do).
|
||||
;;
|
||||
;;
|
||||
;; Immediate integer operand constraints:
|
||||
@ -94,9 +105,9 @@
|
||||
;; some values in bad registers.
|
||||
;;
|
||||
;; 32/64-bit Patterns:
|
||||
;; The 68HC11 does not support 32/64-bit operations. Most of the
|
||||
;; The 68HC11 does not support 32/64-bit operations. Most of the
|
||||
;; 32/64-bit patterns are defined to split the instruction in
|
||||
;; 16-bits patterns. Providing split patterns generates better code
|
||||
;; 16-bits patterns. Providing split patterns generates better code
|
||||
;; than letting GCC implement the 32/64-bit operation itself.
|
||||
;;
|
||||
;;
|
||||
@ -111,7 +122,7 @@
|
||||
;; them correctly (it would treat the X, Y or D register as dead sometimes).
|
||||
;;
|
||||
;; o Some split pattern generate instructions that operate on 'a' or 'b'
|
||||
;; register directory (high part and low part of D respectively).
|
||||
;; register directly (high part and low part of D respectively).
|
||||
;; Such split pattern must also be valid when z_replacement_completed == 2
|
||||
;; because flow/cse is not aware that D is composed of {a, b}.
|
||||
;;
|
||||
@ -3027,139 +3038,261 @@
|
||||
"#")
|
||||
|
||||
(define_insn "andsi3"
|
||||
[(set (match_operand:SI 0 "register_operand" "=D")
|
||||
(and:SI (match_operand:SI 1 "register_operand" "%0")
|
||||
(match_operand:SI 2 "general_operand" "Dimu")))]
|
||||
[(set (match_operand:SI 0 "register_operand" "=D,!u")
|
||||
(and:SI (match_operand:SI 1 "register_operand" "%0,0")
|
||||
(match_operand:SI 2 "general_operand" "Dimu,imu")))
|
||||
(clobber (match_scratch:HI 3 "=X,d"))]
|
||||
""
|
||||
"#")
|
||||
|
||||
(define_insn "andhi3"
|
||||
[(set (match_operand:HI 0 "register_operand" "=d,!u,d,!*A")
|
||||
(and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0")
|
||||
(match_operand:HI 2 "general_operand" "i,i,!um*A,!ium*A")))]
|
||||
(define_expand "andhi3"
|
||||
[(set (match_operand:HI 0 "register_operand" "")
|
||||
(and:HI (match_operand:HI 1 "register_operand" "")
|
||||
(match_operand:HI 2 "general_operand" "")))]
|
||||
""
|
||||
"")
|
||||
|
||||
(define_insn "*andhi3_mem"
|
||||
[(set (match_operand:HI 0 "memory_operand" "=Q,R")
|
||||
(and:HI (match_dup 0)
|
||||
(match_operand:HI 1 "immediate_operand" "i,i")))
|
||||
(clobber (match_scratch:HI 2 "=xy,X"))]
|
||||
"TARGET_RELAX && !TARGET_M6812"
|
||||
"*
|
||||
{
|
||||
int val = INTVAL (operands[1]) & 0x0FFFF;
|
||||
|
||||
if (val == 0x0ffff)
|
||||
{
|
||||
cc_status = cc_prev_status;
|
||||
return \"\";
|
||||
}
|
||||
|
||||
CC_STATUS_INIT;
|
||||
|
||||
/* The bclr instruction uses an inverted mask. */
|
||||
operands[1] = gen_rtx (CONST_INT, VOIDmode, (~val) & 0x0FFFF);
|
||||
|
||||
/* When destination is a global variable, generate a .relax instruction
|
||||
and load the address in the clobber register. That load can be
|
||||
eliminated by the linker if the address is in page0. */
|
||||
if (which_alternative == 0)
|
||||
{
|
||||
rtx ops[3];
|
||||
|
||||
ops[0] = operands[2];
|
||||
ops[1] = XEXP (operands[0], 0);
|
||||
ops[2] = gen_label_rtx ();
|
||||
output_asm_insn (\".relax\\t%l2\", ops);
|
||||
m68hc11_gen_movhi (insn, ops);
|
||||
if ((val & 0x0FF) != 0x0FF)
|
||||
output_asm_insn (\"bclr\\t1,%2, %b1\", operands);
|
||||
|
||||
if ((val & 0x0FF00) != 0x0FF00)
|
||||
output_asm_insn (\"bclr\\t0,%2, %h1\", operands);
|
||||
|
||||
ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
|
||||
CODE_LABEL_NUMBER (ops[2]));
|
||||
return \"\";
|
||||
}
|
||||
|
||||
if ((val & 0x0FF) != 0x0FF)
|
||||
output_asm_insn (\"bclr\\t%b0, %b1\", operands);
|
||||
|
||||
if ((val & 0x0FF00) != 0x0FF00)
|
||||
output_asm_insn (\"bclr\\t%h0, %h1\", operands);
|
||||
|
||||
return \"\";
|
||||
}")
|
||||
|
||||
(define_insn "*andhi3_const"
|
||||
[(set (match_operand:HI 0 "reg_or_some_mem_operand" "=R,d,?*A")
|
||||
(and:HI (match_operand:HI 1 "reg_or_some_mem_operand" "%0,0,0")
|
||||
(match_operand:HI 2 "const_int_operand" "")))]
|
||||
""
|
||||
"*
|
||||
{
|
||||
int val = INTVAL (operands[2]) & 0x0FFFF;
|
||||
int lowpart_zero = 0;
|
||||
int highpart_zero = 0;
|
||||
int lowpart_unknown = 0;
|
||||
int highpart_unknown = 0;
|
||||
|
||||
if (A_REG_P (operands[0]) || H_REG_P (operands[2]))
|
||||
return \"#\";
|
||||
|
||||
if (val == 0x0ffff)
|
||||
{
|
||||
cc_status = cc_prev_status;
|
||||
return \"\";
|
||||
}
|
||||
|
||||
/* First, try to clear the low and high part.
|
||||
If that's possible, the second 'and' will give
|
||||
the good status flags and we can avoid a tsthi. */
|
||||
if ((val & 0x0FF) == 0)
|
||||
{
|
||||
if (D_REG_P (operands[0]))
|
||||
output_asm_insn (\"clrb\", operands);
|
||||
else
|
||||
output_asm_insn (\"clr\\t%b0\", operands);
|
||||
lowpart_zero = 1;
|
||||
}
|
||||
if ((val & 0x0FF00) == 0)
|
||||
{
|
||||
if (D_REG_P (operands[0]))
|
||||
output_asm_insn (\"clra\", operands);
|
||||
else
|
||||
output_asm_insn (\"clr\\t%h0\", operands);
|
||||
highpart_zero = 1;
|
||||
}
|
||||
|
||||
if ((val & 0x0FF) == 0x0FF)
|
||||
{
|
||||
lowpart_unknown = 1;
|
||||
}
|
||||
else if ((val & 0x0FF) != 0 && !H_REG_P (operands[0]))
|
||||
{
|
||||
rtx ops[2];
|
||||
|
||||
ops[0] = operands[0];
|
||||
ops[1] = gen_rtx (CONST_INT, VOIDmode, (~val) & 0x0FF);
|
||||
output_asm_insn (\"bclr\\t%b0, %1\", ops);
|
||||
}
|
||||
else if ((val & 0x0FF) != 0)
|
||||
{
|
||||
output_asm_insn (\"andb\\t%b2\", operands);
|
||||
}
|
||||
|
||||
if ((val & 0x0FF00) == 0x0FF00)
|
||||
{
|
||||
highpart_unknown = 1;
|
||||
}
|
||||
else if (((val & 0x0FF00) != 0) && !H_REG_P (operands[0]))
|
||||
{
|
||||
rtx ops[2];
|
||||
|
||||
ops[0] = operands[0];
|
||||
ops[1] = gen_rtx (CONST_INT, VOIDmode, ((~val) & 0x0FF00) >> 8);
|
||||
output_asm_insn (\"bclr\\t%h0, %1\", ops);
|
||||
}
|
||||
else if ((val & 0x0FF00) != 0)
|
||||
{
|
||||
output_asm_insn (\"anda\\t%h2\", operands);
|
||||
}
|
||||
|
||||
if (highpart_unknown || lowpart_unknown)
|
||||
CC_STATUS_INIT;
|
||||
else if (highpart_zero == 0 && lowpart_zero == 0)
|
||||
CC_STATUS_INIT;
|
||||
|
||||
return \"\";
|
||||
}")
|
||||
|
||||
(define_insn "*andhi3_gen"
|
||||
[(set (match_operand:HI 0 "register_operand" "=d,d,!*A")
|
||||
(and:HI (match_operand:HI 1 "register_operand" "%0,0,0")
|
||||
(match_operand:HI 2 "general_operand" "mi,!u*A,!um*A")))]
|
||||
""
|
||||
"*
|
||||
{
|
||||
if (A_REG_P (operands[0]) || H_REG_P (operands[2]))
|
||||
return \"#\";
|
||||
|
||||
if (GET_CODE (operands[2]) == CONST_INT)
|
||||
{
|
||||
int val = INTVAL (operands[2]) & 0x0FFFF;
|
||||
char lowpart_zero = 0;
|
||||
char lowpart_unknown = 0;
|
||||
char highpart_zero = 0;
|
||||
char highpart_unknown = 0;
|
||||
|
||||
if (val == 0xFFFF)
|
||||
{
|
||||
cc_status = cc_prev_status;
|
||||
return \"\";
|
||||
}
|
||||
|
||||
/* First, try to clear the low and high part.
|
||||
If that's possible, the second 'and' will give
|
||||
the good status flags and we can avoid a tsthi. */
|
||||
if ((val & 0x0FF) == 0)
|
||||
{
|
||||
if (D_REG_P (operands[0]))
|
||||
output_asm_insn (\"clrb\", operands);
|
||||
else
|
||||
output_asm_insn (\"clr\\t%b0\", operands);
|
||||
lowpart_zero = 1;
|
||||
}
|
||||
if ((val & 0x0FF00) == 0)
|
||||
{
|
||||
if (D_REG_P (operands[0]))
|
||||
output_asm_insn (\"clra\", operands);
|
||||
else
|
||||
output_asm_insn (\"clr\\t%h0\", operands);
|
||||
highpart_zero = 1;
|
||||
}
|
||||
|
||||
if ((val & 0x0FF) == 0x0FF)
|
||||
{
|
||||
lowpart_unknown = 1;
|
||||
}
|
||||
else if ((val & 0x0FF) != 0 && !H_REG_P (operands[0]))
|
||||
{
|
||||
rtx ops[2];
|
||||
|
||||
ops[0] = operands[0];
|
||||
ops[1] = gen_rtx (CONST_INT, VOIDmode, (~val) & 0x0FF);
|
||||
output_asm_insn (\"bclr\\t%b0, %1\", ops);
|
||||
}
|
||||
else if ((val & 0x0FF) != 0)
|
||||
{
|
||||
output_asm_insn (\"andb\\t%b2\", operands);
|
||||
}
|
||||
|
||||
if ((val & 0x0FF00) == 0x0FF00)
|
||||
{
|
||||
highpart_unknown = 1;
|
||||
}
|
||||
else if (((val & 0x0FF00) != 0) && !H_REG_P (operands[0]))
|
||||
{
|
||||
rtx ops[2];
|
||||
|
||||
ops[0] = operands[0];
|
||||
ops[1] = gen_rtx (CONST_INT, VOIDmode, ((~val) & 0x0FF00) >> 8);
|
||||
output_asm_insn (\"bclr\\t%h0, %1\", ops);
|
||||
}
|
||||
else if ((val & 0x0FF00) != 0)
|
||||
{
|
||||
output_asm_insn (\"anda\\t%h2\", operands);
|
||||
}
|
||||
|
||||
if (highpart_unknown || lowpart_unknown)
|
||||
CC_STATUS_INIT;
|
||||
else if (highpart_zero == 0 && lowpart_zero == 0)
|
||||
CC_STATUS_INIT;
|
||||
|
||||
return \"\";
|
||||
}
|
||||
|
||||
CC_STATUS_INIT;
|
||||
return \"andb\\t%b2\\n\\tanda\\t%h2\";
|
||||
}")
|
||||
|
||||
(define_insn "andqi3"
|
||||
[(set (match_operand:QI 0 "register_operand" "=d,!u,d,d,?*A,?*A,!*q")
|
||||
(and:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0,0,0")
|
||||
(match_operand:QI 2 "general_operand" "i,i,!um,?*A,!ium,?*A*d,!ium*A")))]
|
||||
(define_expand "andqi3"
|
||||
[(set (match_operand:QI 0 "register_operand" "")
|
||||
(and:QI (match_operand:QI 1 "register_operand" "")
|
||||
(match_operand:QI 2 "general_operand" "")))]
|
||||
""
|
||||
"")
|
||||
|
||||
(define_insn "*andqi3_mem"
|
||||
[(set (match_operand:QI 0 "memory_operand" "=Q,R")
|
||||
(and:QI (match_dup 0)
|
||||
(match_operand:QI 1 "const_int_operand" "i,i")))
|
||||
(clobber (match_scratch:HI 2 "=xy,X"))]
|
||||
"TARGET_RELAX && !TARGET_M6812"
|
||||
"*
|
||||
{
|
||||
int val = INTVAL (operands[1]) & 0x0FF;
|
||||
|
||||
if (val == 0x0ff)
|
||||
{
|
||||
cc_status = cc_prev_status;
|
||||
return \"\";
|
||||
}
|
||||
|
||||
/* The bclr instruction uses an inverted mask. */
|
||||
operands[1] = gen_rtx (CONST_INT, VOIDmode, (~val) & 0x0FF);
|
||||
|
||||
/* When destination is a global variable, generate a .relax instruction
|
||||
and load the address in the clobber register. That load can be
|
||||
eliminated by the linker if the address is in page0. */
|
||||
if (which_alternative == 0)
|
||||
{
|
||||
rtx ops[3];
|
||||
|
||||
ops[0] = operands[2];
|
||||
ops[1] = XEXP (operands[0], 0);
|
||||
ops[2] = gen_label_rtx ();
|
||||
output_asm_insn (\".relax\\t%l2\", ops);
|
||||
m68hc11_gen_movhi (insn, ops);
|
||||
output_asm_insn (\"bclr\\t0,%2, %1\", operands);
|
||||
ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
|
||||
CODE_LABEL_NUMBER (ops[2]));
|
||||
return \"\";
|
||||
}
|
||||
return \"bclr\\t%b0, %1\";
|
||||
}")
|
||||
|
||||
(define_insn "*andqi3_const"
|
||||
[(set (match_operand:QI 0 "reg_or_some_mem_operand" "=R,d,?*A*q")
|
||||
(and:QI (match_operand:QI 1 "reg_or_some_mem_operand" "%0,0,0")
|
||||
(match_operand:QI 2 "const_int_operand" "")))]
|
||||
""
|
||||
"*
|
||||
{
|
||||
int val = INTVAL (operands[2]) & 0x0FF;
|
||||
|
||||
if (A_REG_P (operands[0]) || H_REG_P (operands[2]))
|
||||
return \"#\";
|
||||
|
||||
if (val == 0x0ff)
|
||||
{
|
||||
cc_status = cc_prev_status;
|
||||
return \"\";
|
||||
}
|
||||
if (!H_REG_P (operands[0]))
|
||||
{
|
||||
rtx ops[2];
|
||||
|
||||
ops[0] = operands[0];
|
||||
ops[1] = gen_rtx (CONST_INT, VOIDmode, (~val) & 0x0FF);
|
||||
output_asm_insn (\"bclr\\t%b0, %b1\", ops);
|
||||
return \"\";
|
||||
}
|
||||
if (D_REG_P (operands[0]) || DB_REG_P (operands[0]))
|
||||
return \"andb\\t%b2\";
|
||||
else if (DA_REG_P (operands[0]))
|
||||
return \"anda\\t%b2\";
|
||||
else
|
||||
fatal_insn (\"Invalid operand in the instruction\", insn);
|
||||
}")
|
||||
|
||||
(define_insn "*andqi3_gen"
|
||||
[(set (match_operand:QI 0 "register_operand" "=d,d,d,?*A,?*A,!*q")
|
||||
(and:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0,0")
|
||||
(match_operand:QI 2 "general_operand" "mi,!u,?*A,!um,?*A*d,!um*A")))]
|
||||
""
|
||||
"*
|
||||
{
|
||||
if (A_REG_P (operands[0]) || H_REG_P (operands[2]))
|
||||
return \"#\";
|
||||
|
||||
if (GET_CODE (operands[2]) == CONST_INT)
|
||||
{
|
||||
int val = INTVAL (operands[2]) & 0x0FF;
|
||||
|
||||
if (val == 0xFF)
|
||||
{
|
||||
cc_status = cc_prev_status;
|
||||
return \"\";
|
||||
}
|
||||
if (val == 0)
|
||||
{
|
||||
if (D_REG_P (operands[0]) || DB_REG_P (operands[0]))
|
||||
return \"clrb\";
|
||||
else if (DA_REG_P (operands[0]))
|
||||
return \"clra\";
|
||||
else
|
||||
return \"clr\\t%b0\";
|
||||
}
|
||||
if (!H_REG_P (operands[0]))
|
||||
{
|
||||
rtx ops[2];
|
||||
ops[0] = operands[0];
|
||||
ops[1] = gen_rtx (CONST_INT, VOIDmode, (~val) & 0x0FF);
|
||||
output_asm_insn (\"bclr\\t%b0, %b1\", ops);
|
||||
return \"\";
|
||||
}
|
||||
}
|
||||
if (D_REG_P (operands[0]) || DB_REG_P (operands[0]))
|
||||
return \"andb\\t%b2\";
|
||||
else if (DA_REG_P (operands[0]))
|
||||
@ -3181,79 +3314,177 @@
|
||||
"#")
|
||||
|
||||
(define_insn "iorsi3"
|
||||
[(set (match_operand:SI 0 "register_operand" "=D")
|
||||
(ior:SI (match_operand:SI 1 "register_operand" "%0")
|
||||
(match_operand:SI 2 "general_operand" "Dimu")))]
|
||||
[(set (match_operand:SI 0 "register_operand" "=D,!u")
|
||||
(ior:SI (match_operand:SI 1 "register_operand" "%0,0")
|
||||
(match_operand:SI 2 "general_operand" "Dimu,imu")))
|
||||
(clobber (match_scratch:HI 3 "=X,d"))]
|
||||
""
|
||||
"#")
|
||||
|
||||
(define_insn "iorhi3"
|
||||
[(set (match_operand:HI 0 "register_operand" "=d,!u,d,!*A")
|
||||
(ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0")
|
||||
(match_operand:HI 2 "general_operand" "i,i,!um*A,!ium*A")))]
|
||||
(define_expand "iorhi3"
|
||||
[(set (match_operand:HI 0 "register_operand" "")
|
||||
(ior:HI (match_operand:HI 1 "register_operand" "")
|
||||
(match_operand:HI 2 "general_operand" "")))]
|
||||
""
|
||||
"")
|
||||
|
||||
(define_insn "*iorhi3_mem"
|
||||
[(set (match_operand:HI 0 "memory_operand" "=Q,R")
|
||||
(ior:HI (match_dup 0)
|
||||
(match_operand:HI 1 "const_int_operand" "")))
|
||||
(clobber (match_scratch:HI 2 "=xy,X"))]
|
||||
"TARGET_RELAX && !TARGET_M6812"
|
||||
"*
|
||||
{
|
||||
int val = INTVAL (operands[1]) & 0x0FFFF;
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
cc_status = cc_prev_status;
|
||||
return \"\";
|
||||
}
|
||||
CC_STATUS_INIT;
|
||||
if (which_alternative == 0)
|
||||
{
|
||||
rtx ops[3];
|
||||
|
||||
ops[0] = operands[2];
|
||||
ops[1] = XEXP (operands[0], 0);
|
||||
ops[2] = gen_label_rtx ();
|
||||
output_asm_insn (\".relax\\t%l2\", ops);
|
||||
m68hc11_gen_movhi (insn, ops);
|
||||
if ((val & 0x0FF) != 0)
|
||||
output_asm_insn (\"bset\\t1,%2, %b1\", operands);
|
||||
|
||||
if ((val & 0x0FF00) != 0)
|
||||
output_asm_insn (\"bset\\t0,%2, %h1\", operands);
|
||||
ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
|
||||
CODE_LABEL_NUMBER (ops[2]));
|
||||
return \"\";
|
||||
}
|
||||
|
||||
if ((val & 0x0FF) != 0)
|
||||
output_asm_insn (\"bset\\t%b0, %b1\", operands);
|
||||
|
||||
if ((val & 0x0FF00) != 0)
|
||||
output_asm_insn (\"bset\\t%h0, %h1\", operands);
|
||||
|
||||
return \"\";
|
||||
}")
|
||||
|
||||
(define_insn "*iorhi3_const"
|
||||
[(set (match_operand:HI 0 "reg_or_some_mem_operand" "=R,d,?*A")
|
||||
(ior:HI (match_operand:HI 1 "reg_or_some_mem_operand" "%0,0,0")
|
||||
(match_operand:HI 2 "const_int_operand" "")))]
|
||||
""
|
||||
"*
|
||||
{
|
||||
int val = INTVAL (operands[2]) & 0x0FFFF;
|
||||
|
||||
if (A_REG_P (operands[0]) || H_REG_P (operands[2]))
|
||||
return \"#\";
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
cc_status = cc_prev_status;
|
||||
return \"\";
|
||||
}
|
||||
|
||||
if ((val & 0x0FF) != 0)
|
||||
{
|
||||
if (!H_REG_P (operands[0]))
|
||||
output_asm_insn (\"bset\\t%b0, %b2\", operands);
|
||||
else
|
||||
output_asm_insn (\"orab\\t%b2\", operands);
|
||||
}
|
||||
|
||||
if ((val & 0x0FF00) != 0)
|
||||
{
|
||||
if (!H_REG_P (operands[0]))
|
||||
output_asm_insn (\"bset\\t%h0, %h2\", operands);
|
||||
else
|
||||
output_asm_insn (\"oraa\\t%h2\", operands);
|
||||
}
|
||||
|
||||
CC_STATUS_INIT;
|
||||
return \"\";
|
||||
}")
|
||||
|
||||
(define_insn "*iorhi3_gen"
|
||||
[(set (match_operand:HI 0 "register_operand" "=d,d,!*A")
|
||||
(ior:HI (match_operand:HI 1 "register_operand" "%0,0,0")
|
||||
(match_operand:HI 2 "general_operand" "mi,!u*A,!um*A")))]
|
||||
""
|
||||
"*
|
||||
{
|
||||
if (A_REG_P (operands[0]) || H_REG_P (operands[2]))
|
||||
return \"#\";
|
||||
|
||||
if (GET_CODE (operands[2]) == CONST_INT)
|
||||
{
|
||||
int val = INTVAL (operands[2]) & 0x0FFFF;
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
cc_status = cc_prev_status;
|
||||
return \"\";
|
||||
}
|
||||
if ((val & 0x0FF) != 0)
|
||||
{
|
||||
if (!H_REG_P (operands[0]))
|
||||
output_asm_insn (\"bset\\t%b0, %b2\", operands);
|
||||
else
|
||||
output_asm_insn (\"orab\\t%b2\", operands);
|
||||
}
|
||||
|
||||
if ((val & 0x0FF00) != 0)
|
||||
{
|
||||
if (!H_REG_P (operands[0]))
|
||||
output_asm_insn (\"bset\\t%h0, %h2\", operands);
|
||||
else
|
||||
output_asm_insn (\"oraa\\t%h2\", operands);
|
||||
}
|
||||
|
||||
CC_STATUS_INIT;
|
||||
return \"\";
|
||||
}
|
||||
|
||||
CC_STATUS_INIT;
|
||||
return \"orab\\t%b2\\n\\toraa\\t%h2\";
|
||||
}")
|
||||
|
||||
(define_insn "iorqi3"
|
||||
[(set (match_operand:QI 0 "register_operand" "=d,!u,d,d,?*A,?*A,!*q")
|
||||
(ior:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0,0,0")
|
||||
(match_operand:QI 2 "general_operand" "i,i,!um,!*A,!ium,?*A*d,!ium*A")))]
|
||||
(define_expand "iorqi3"
|
||||
[(set (match_operand:QI 0 "register_operand" "")
|
||||
(ior:QI (match_operand:QI 1 "register_operand" "")
|
||||
(match_operand:QI 2 "general_operand" "")))]
|
||||
""
|
||||
"")
|
||||
|
||||
(define_insn "*iorqi3_mem"
|
||||
[(set (match_operand:QI 0 "memory_operand" "=Q,R")
|
||||
(ior:QI (match_dup 0)
|
||||
(match_operand:QI 1 "const_int_operand" "")))
|
||||
(clobber (match_scratch:HI 2 "=xy,X"))]
|
||||
"TARGET_RELAX && !TARGET_M6812"
|
||||
"*
|
||||
{
|
||||
int val = INTVAL (operands[1]) & 0x0FF;
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
cc_status = cc_prev_status;
|
||||
return \"\";
|
||||
}
|
||||
if (which_alternative == 0)
|
||||
{
|
||||
rtx ops[3];
|
||||
|
||||
ops[0] = operands[2];
|
||||
ops[1] = XEXP (operands[0], 0);
|
||||
ops[2] = gen_label_rtx ();
|
||||
output_asm_insn (\".relax\\t%l2\", ops);
|
||||
m68hc11_gen_movhi (insn, ops);
|
||||
output_asm_insn (\"bset\\t0,%2, %1\", operands);
|
||||
ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
|
||||
CODE_LABEL_NUMBER (ops[2]));
|
||||
return \"\";
|
||||
}
|
||||
return \"bset\\t%b0, %1\";
|
||||
}")
|
||||
|
||||
(define_insn "*iorqi3_const"
|
||||
[(set (match_operand:QI 0 "reg_or_some_mem_operand" "=R,d,?*A*q")
|
||||
(ior:QI (match_operand:QI 1 "reg_or_some_mem_operand" "%0,0,0")
|
||||
(match_operand:QI 2 "const_int_operand" "")))]
|
||||
""
|
||||
"*
|
||||
{
|
||||
int val = INTVAL (operands[2]) & 0x0FF;
|
||||
|
||||
if (A_REG_P (operands[0]) || H_REG_P (operands[2]))
|
||||
return \"#\";
|
||||
|
||||
if (GET_CODE (operands[2]) == CONST_INT)
|
||||
if (val == 0)
|
||||
{
|
||||
int val = INTVAL (operands[2]) & 0x0FF;
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
cc_status = cc_prev_status;
|
||||
return \"\";
|
||||
}
|
||||
if (!H_REG_P (operands[0]))
|
||||
{
|
||||
return \"bset\\t%b0, %2\";
|
||||
}
|
||||
cc_status = cc_prev_status;
|
||||
return \"\";
|
||||
}
|
||||
if (!H_REG_P (operands[0]))
|
||||
{
|
||||
return \"bset\\t%b0, %2\";
|
||||
}
|
||||
|
||||
if (D_REG_P (operands[0]) || DB_REG_P (operands[0]))
|
||||
return \"orab\\t%b2\";
|
||||
else if (DA_REG_P (operands[0]))
|
||||
@ -3262,6 +3493,25 @@
|
||||
fatal_insn (\"Invalid operand in the instruction\", insn);
|
||||
}")
|
||||
|
||||
(define_insn "*iorqi3_gen"
|
||||
[(set (match_operand:QI 0 "register_operand" "=d,d,d,?*A,?*A,!*q")
|
||||
(ior:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0,0")
|
||||
(match_operand:QI 2 "general_operand" "mi,!u,!*A,!um,?*A*d,!um*A")))]
|
||||
""
|
||||
"*
|
||||
{
|
||||
if (A_REG_P (operands[0]) || H_REG_P (operands[2]))
|
||||
return \"#\";
|
||||
|
||||
if (D_REG_P (operands[0]) || DB_REG_P (operands[0]))
|
||||
return \"orab\\t%b2\";
|
||||
else if (DA_REG_P (operands[0]))
|
||||
return \"oraa\\t%b2\";
|
||||
else
|
||||
fatal_insn (\"Invalid operand in the instruction\", insn);
|
||||
}")
|
||||
|
||||
|
||||
;;--------------------------------------------------------------------
|
||||
;;- xor instructions.
|
||||
;;--------------------------------------------------------------------
|
||||
@ -3275,9 +3525,10 @@
|
||||
"#")
|
||||
|
||||
(define_insn "xorsi3"
|
||||
[(set (match_operand:SI 0 "register_operand" "=D")
|
||||
(xor:SI (match_operand:SI 1 "register_operand" "%0")
|
||||
(match_operand:SI 2 "general_operand" "Dimu")))]
|
||||
[(set (match_operand:SI 0 "register_operand" "=D,!u")
|
||||
(xor:SI (match_operand:SI 1 "register_operand" "%0,0")
|
||||
(match_operand:SI 2 "general_operand" "Dimu,imu")))
|
||||
(clobber (match_scratch:HI 3 "=X,d"))]
|
||||
""
|
||||
"#")
|
||||
|
||||
@ -3329,7 +3580,7 @@
|
||||
(define_insn "xorqi3"
|
||||
[(set (match_operand:QI 0 "register_operand" "=d,d,d,?*A,?*A,!*q")
|
||||
(xor:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0,0")
|
||||
(match_operand:QI 2 "general_operand" "i,!um,!*A,!ium,?*A*d,!ium*A")))]
|
||||
(match_operand:QI 2 "general_operand" "im,!u,!*A,!ium,?*A*d,!ium*A")))]
|
||||
""
|
||||
"*
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user