{
fprintf (stream, "\t/*abuse empty parameter slot for locals!*/\n");
if (size > 2)
- fprintf(stream, "\tsub $%d, sp\n", size - 2);
+ fprintf(stream, "\tsub $0%o, sp\n", size - 2);
}
}
if (frame_pointer_needed)
{
- fprintf(stream, "\tmov fp, -(sp)\n");
- fprintf(stream, "\tmov sp, fp\n");
+ fprintf(stream, "\tmov r5, -(sp)\n");
+ fprintf(stream, "\tmov sp, r5\n");
}
else
{
/* make frame */
if (fsize)
- fprintf (stream, "\tsub $%o, sp\n", fsize);
+ fprintf (stream, "\tsub $0%o, sp\n", fsize);
/* save CPU registers */
for (regno = 0; regno < 8; regno++)
&& regs_ever_live[regno]
&& ! call_used_regs[regno])
{
- fprintf (stream, "\tfstd %s, -(sp)\n", reg_names[regno]);
+ fprintf (stream, "\tstd %s, -(sp)\n", reg_names[regno]);
via_ac = regno;
}
if (via_ac == -1)
abort();
- fprintf (stream, "\tfldd %s, %s\n", reg_names[regno], reg_names[via_ac]);
- fprintf (stream, "\tfstd %s, -(sp)\n", reg_names[via_ac]);
+ fprintf (stream, "\tldd %s, %s\n", reg_names[regno], reg_names[via_ac]);
+ fprintf (stream, "\tstd %s, -(sp)\n", reg_names[via_ac]);
}
}
/* remember # of pushed bytes for CPU regs */
k = 2*j;
+ /* change fp -> r5 due to the compile error on libgcc2.c */
for (i =7 ; i >= 0 ; i--)
if (regs_ever_live[i] && ! call_used_regs[i])
- fprintf(stream, "\tmov %o(fp), %s\n",-fsize-2*j--, reg_names[i]);
+ fprintf(stream, "\tmov 0%o(r5), %s\n",(-fsize-2*j--)&0xffff, reg_names[i]);
/* get ACs */
via_ac = FIRST_PSEUDO_REGISTER -1;
&& regs_ever_live[i]
&& ! call_used_regs[i])
{
- fprintf(stream, "\tfldd %o(fp), %s\n", -fsize-k, reg_names[i]);
+ fprintf(stream, "\tldd 0%o(r5), %s\n", (-fsize-k)&0xffff, reg_names[i]);
k -= 8;
}
if (! LOAD_FPU_REG_P(via_ac))
abort();
- fprintf(stream, "\tfldd %o(fp), %s\n", -fsize-k, reg_names[via_ac]);
- fprintf(stream, "\tfstd %s, %s\n", reg_names[via_ac], reg_names[i]);
+ fprintf(stream, "\tldd 0%o(r5), %s\n", (-fsize-k)&0xffff, reg_names[via_ac]);
+ fprintf(stream, "\tstd %s, %s\n", reg_names[via_ac], reg_names[i]);
k -= 8;
}
}
- fprintf(stream, "\tmov fp, sp\n");
- fprintf (stream, "\tmov (sp)+, fp\n");
+ fprintf(stream, "\tmov r5, sp\n");
+ fprintf (stream, "\tmov (sp)+, r5\n");
}
else
{
if (LOAD_FPU_REG_P(i)
&& regs_ever_live[i]
&& ! call_used_regs[i])
- fprintf(stream, "\tfldd (sp)+, %s\n", reg_names[i]);
+ fprintf(stream, "\tldd (sp)+, %s\n", reg_names[i]);
if (NO_LOAD_FPU_REG_P(i)
&& regs_ever_live[i]
if (! LOAD_FPU_REG_P(via_ac))
abort();
- fprintf(stream, "\tfldd (sp)+, %s\n", reg_names[via_ac]);
- fprintf(stream, "\tfstd %s, %s\n", reg_names[via_ac], reg_names[i]);
+ fprintf(stream, "\tldd (sp)+, %s\n", reg_names[via_ac]);
+ fprintf(stream, "\tstd %s, %s\n", reg_names[via_ac], reg_names[i]);
}
}
fprintf(stream, "\tmov (sp)+, %s\n", reg_names[i]);
if (fsize)
- fprintf((stream), "\tadd $%o, sp\n", fsize);
+ fprintf((stream), "\tadd $0%o, sp\n", (fsize)&0xffff);
}
fprintf (stream, "\trts pc\n");
rtx latehalf[2];
rtx addreg0 = 0, addreg1 = 0;
- output_asm_insn(";; movdi/df: %1 -> %0", operands);
+ output_asm_insn(";/* movdi/df: %1 -> %0 */", operands);
if (REG_P (operands[0]))
optype0 = REGOP;
register int c = p[i];
if (c < 0)
c += 256;
- fprintf (file, "%o", c);
+ fprintf (file, "0%o", c);
if (i < size - 1)
putc (',', file);
}
fprintf (file, "(%s)", reg_names[REGNO (addr)]);
break;
+ case PRE_MODIFY:
case PRE_DEC:
fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
break;
+ case POST_MODIFY:
case POST_INC:
fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
break;
case CONST_INT:
/* Should we check for constants which are too big? Maybe cutting
them off to 16 bits is OK? */
- fprintf (file, "%ho", (unsigned short) INTVAL (x));
+ fprintf (file, "0%ho", (unsigned short) INTVAL (x));
break;
case CONST:
if (CONST_DOUBLE_HIGH (x))
abort (); /* Should we just silently drop the high part? */
else
- fprintf (file, "%ho", (unsigned short) CONST_DOUBLE_LOW (x));
+ fprintf (file, "0%ho", (unsigned short) CONST_DOUBLE_LOW (x));
}
else
/* We can't handle floating point constants;
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+#define CONSTANT_POOL_BEFORE_FUNCTION 0
/* check whether load_fpu_reg or not */
#define LOAD_FPU_REG_P(x) ((x)>=8 && (x)<=11)
/* Nonzero if the constant value X is a legitimate general operand.
It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
-#define LEGITIMATE_CONSTANT_P(X) (1)
+#define LEGITIMATE_CONSTANT_P(X) (TARGET_FPU? 1: !(GET_CODE(X) == CONST_DOUBLE))
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class.
&& GET_CODE (XEXP (operand, 0)) == REG \
&& REG_OK_FOR_BASE_P (XEXP (operand, 0))) \
goto ADDR; \
+ \
+ /* accept -(SP) -- which uses PRE_MODIFY for byte mode */ \
+ if (GET_CODE (operand) == PRE_MODIFY \
+ && GET_CODE (XEXP (operand, 0)) == REG \
+ && REGNO (XEXP (operand, 0)) == 6 \
+ && GET_CODE ((xfoob = XEXP (operand, 1))) == PLUS \
+ && GET_CODE (XEXP (xfoob, 0)) == REG \
+ && REGNO (XEXP (xfoob, 0)) == 6 \
+ && CONSTANT_P (XEXP (xfoob, 1)) \
+ && INTVAL (XEXP (xfoob,1)) == -2) \
+ goto ADDR; \
+ \
+ /* accept (SP)+ -- which uses POST_MODIFY for byte mode */ \
+ if (GET_CODE (operand) == POST_MODIFY \
+ && GET_CODE (XEXP (operand, 0)) == REG \
+ && REGNO (XEXP (operand, 0)) == 6 \
+ && GET_CODE ((xfoob = XEXP (operand, 1))) == PLUS \
+ && GET_CODE (XEXP (xfoob, 0)) == REG \
+ && REGNO (XEXP (xfoob, 0)) == 6 \
+ && CONSTANT_P (XEXP (xfoob, 1)) \
+ && INTVAL (XEXP (xfoob,1)) == 2) \
+ goto ADDR; \
+ \
\
/* handle another level of indirection ! */ \
if (GET_CODE(operand) != MEM) \
char buf[30]; \
REAL_VALUE_FROM_CONST_DOUBLE (r, X); \
REAL_VALUE_TO_DECIMAL (r, buf, -1); \
- fprintf (FILE, "#%s", buf); } \
+ fprintf (FILE, "$0F%s", buf); } \
else { putc ('$', FILE); output_addr_const_pdp11 (FILE, X); }}
\f
/* Print a memory address as an operand to reference that memory location. */
;; Move instructions
(define_insn "movdi"
- [(set (match_operand:DI 0 "general_operand" "=g")
- (match_operand:DI 1 "general_operand" "g"))]
+ [(set (match_operand:DI 0 "general_operand" "=g,rm,m")
+ (match_operand:DI 1 "general_operand" "m,r,a"))]
""
"* return output_move_quad (operands);"
;; what's the mose expensive code - say twice movsi = 16
- [(set_attr "length" "16")])
+ [(set_attr "length" "16,16,16")])
(define_insn "movsi"
[(set (match_operand:SI 0 "general_operand" "=r,r,r,rm,m")
[(set_attr "length" "1,2,2,3")])
(define_insn "movqi"
- [(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
- (match_operand:QI 1 "general_operand" "rRN,Qi,rRN,Qi"))]
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=g")
+ (match_operand:QI 1 "general_operand" "g"))]
""
"*
{
return \"movb %1, %0\";
}"
- [(set_attr "length" "1,2,2,3")])
+ [(set_attr "length" "1")])
;; do we have to supply all these moves? e.g. to
;; NO_LOAD_FPU_REGs ?
(define_insn "movdf"
- [(set (match_operand:DF 0 "general_operand" "=f,R,f,Q,f,m")
- (match_operand:DF 1 "general_operand" "fR,f,Q,f,F,m"))]
+ [(set (match_operand:DF 0 "general_operand" "=a,fR,a,Q,m")
+ (match_operand:DF 1 "general_operand" "fFR,a,Q,a,m"))]
""
- "* return output_move_quad (operands);"
+ "* if (which_alternative ==0)
+ return \"ldd %1, %0\";
+ else if (which_alternative == 1)
+ return \"std %1, %0\";
+ else
+ return output_move_quad (operands); "
;; just a guess..
- [(set_attr "length" "1,1,2,2,5,16")])
+ [(set_attr "length" "1,1,5,5,16")])
(define_insn "movsf"
[(set (match_operand:SF 0 "general_operand" "=g,r,g")
[(set (match_operand:HI 0 "general_operand" "=r")
(zero_extend:HI (match_operand:QI 1 "general_operand" "0")))]
""
- "bic $(256*255), %0"
+ "bic $0177400, %0"
[(set_attr "length" "2")])
(define_expand "zero_extendhisi2"
rtx latehalf[2];
latehalf[0] = NULL;
- latehalf[1] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
+ latehalf[1] = gen_rtx_REG (HImode, REGNO (operands[1]) + 1);
output_asm_insn(\"mov %1, -(sp)\", latehalf);
output_asm_insn(\"mov %1, -(sp)\", operands);
return \"decb %0\";
}
- return \"addb %2, %0\";
+ return \"add %2, %0\";
}"
[(set_attr "length" "1,2,2,3")])
if (GET_CODE (operands[2]) == CONST_INT)
abort();
- return \"subb %2, %0\";
+ return \"sub %2, %0\";
}"
[(set_attr "length" "1,2,2,3")])
;;;;- and instructions
;; Bit-and on the pdp (like on the VAX) is done with a clear-bits insn.
-(define_expand "andsi3"
- [(set (match_operand:SI 0 "general_operand" "=g")
- (and:SI (match_operand:SI 1 "general_operand" "0")
- (not:SI (match_operand:SI 2 "general_operand" "g"))))]
- ""
- "
-{
- if (GET_CODE (operands[2]) == CONST_INT)
- operands[2] = GEN_INT (~INTVAL (operands[2]));
- else
- operands[2] = expand_unop (SImode, one_cmpl_optab, operands[2], 0, 1);
-}")
-(define_expand "andhi3"
- [(set (match_operand:HI 0 "general_operand" "=g")
- (and:HI (match_operand:HI 1 "general_operand" "0")
- (not:HI (match_operand:HI 2 "general_operand" "g"))))]
- ""
- "
-{
- if (GET_CODE (operands[2]) == CONST_INT)
- operands[2] = GEN_INT (~INTVAL (operands[2]));
- else
- operands[2] = expand_unop (HImode, one_cmpl_optab, operands[2], 0, 1);
-}")
-
-(define_expand "andqi3"
- [(set (match_operand:QI 0 "general_operand" "=g")
- (and:QI (match_operand:QI 1 "general_operand" "0")
- (not:QI (match_operand:QI 2 "general_operand" "g"))))]
- ""
- "
-{
- rtx op = operands[2];
- if (GET_CODE (op) == CONST_INT)
- operands[2] = GEN_INT (((1 << 8) - 1) & ~INTVAL (op));
- else
- operands[2] = expand_unop (QImode, one_cmpl_optab, op, 0, 1);
-}")
-
-(define_insn "andcbsi3"
+(define_insn "andsi3"
[(set (match_operand:SI 0 "general_operand" "=r,r,o,o,r,r,r,o,o,o")
(and:SI (match_operand:SI 1 "general_operand" "%0,0,0,0,0,0,0,0,0,0")
(not:SI (match_operand:SI 2 "general_operand" "r,o,r,o,I,J,K,I,J,K"))))]
}"
[(set_attr "length" "2,4,4,6,2,2,4,3,3,6")])
-(define_insn "andcbhi3"
+(define_insn "andhi3"
[(set (match_operand:HI 0 "general_operand" "=rR,rR,Q,Q")
(and:HI (match_operand:HI 1 "general_operand" "0,0,0,0")
(not:HI (match_operand:HI 2 "general_operand" "rR,Qi,rR,Qi"))))]
"bic %2, %0"
[(set_attr "length" "1,2,2,3")])
-(define_insn "andcbqi3"
+(define_insn "andqi3"
[(set (match_operand:QI 0 "general_operand" "=rR,rR,Q,Q")
(and:QI (match_operand:QI 1 "general_operand" "0,0,0,0")
(not:QI (match_operand:QI 2 "general_operand" "rR,Qi,rR,Qi"))))]
;;- xor instructions
(define_insn "xorsi3"
- [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
- (xor:SI (match_operand:SI 1 "register_operand" "%0,0,0,0")
- (match_operand:SI 2 "arith_operand" "r,I,J,K")))]
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (xor:SI (match_operand:SI 1 "register_operand" "%0")
+ (match_operand:SI 2 "arith_operand" "r")))]
"TARGET_40_PLUS"
"*
{ /* Here we trust that operands don't overlap */
return \"\";
}
- lateoperands[2] = GEN_INT ((INTVAL (operands[2]) >> 16) & 0xffff);
- operands[2] = GEN_INT (INTVAL(operands[2]) & 0xffff);
-
- if (INTVAL (operands[2]))
- output_asm_insn (\"xor %2, %0\", operands);
-
- if (INTVAL (lateoperands[2]))
- output_asm_insn (\"xor %2, %0\", lateoperands);
-
- return \"\";
}"
- [(set_attr "length" "2,1,1,2")])
+ [(set_attr "length" "2")])
(define_insn "xorhi3"
[(set (match_operand:HI 0 "general_operand" "=rR,Q")
[(set_attr "length" "1,2")])
(define_insn "one_cmplqi2"
- [(set (match_operand:QI 0 "general_operand" "=rR,Q")
- (not:QI (match_operand:QI 1 "general_operand" "0,0")))]
+ [(set (match_operand:QI 0 "general_operand" "=rR,rR")
+ (not:QI (match_operand:QI 1 "general_operand" "0,g")))]
""
- "comb %0"
+ "@
+ comb %0
+ movb %1, %0\; comb %0"
[(set_attr "length" "1,2")])
;;- arithmetic shift instructions
"asr %0"
[(set_attr "length" "1,2")])
+;; lsr
+(define_insn ""
+ [(set (match_operand:HI 0 "general_operand" "=rR,Q")
+ (lshiftrt:HI (match_operand:HI 1 "general_operand" "0,0")
+ (const_int 1)))]
+ ""
+ "clc\;ror %0"
+ [(set_attr "length" "1,2")])
+
+(define_insn "lshrsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
+ (const_int 1)))]
+ ""
+{ /* Here we trust that operands don't overlap */
+
+ rtx lateoperands[2];
+
+ lateoperands[0] = operands[0];
+ operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
+
+ lateoperands[1] = operands[1];
+ operands[1] = gen_rtx_REG (HImode, REGNO (operands[1]) + 1);
+
+ output_asm_insn (\"clc\", operands);
+ output_asm_insn (\"ror %0\", lateoperands);
+ output_asm_insn (\"ror %0\", operands);
+
+ return \"\";
+}
+ [(set_attr "length" "5")])
+
;; shift is by arbitrary count is expensive,
;; shift by one cheap - so let's do that, if
;; space doesn't matter
"{negd|negf} %0"
[(set_attr "length" "1,2")])
+(define_insn "negsi2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (neg:SI (match_operand:SI 1 "general_operand" "0")))]
+ ""
+{ /* Here we trust that operands don't overlap */
+
+ rtx lateoperands[2];
+
+ lateoperands[0] = operands[0];
+ operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
+
+ lateoperands[1] = operands[1];
+ operands[1] = gen_rtx_REG (HImode, REGNO (operands[1]) + 1);
+
+ output_asm_insn (\"com %0\", operands);
+ output_asm_insn (\"com %0\", lateoperands);
+ output_asm_insn (\"inc %0\", operands);
+ output_asm_insn (\"adc %0\", lateoperands);
+
+ return \"\";
+}
+ [(set_attr "length" "5")])
+
(define_insn "neghi2"
[(set (match_operand:HI 0 "general_operand" "=rR,Q")
(neg:HI (match_operand:HI 1 "general_operand" "0,0")))]
;;- jump to subroutine
(define_insn "call"
- [(call (match_operand:HI 0 "general_operand" "R,Q")
+ [(call (match_operand:HI 0 "general_operand" "rR,Q")
(match_operand:HI 1 "general_operand" "g,g"))
;; (use (reg:HI 0)) what was that ???
]
;;- jump to subroutine
(define_insn "call_value"
[(set (match_operand 0 "" "")
- (call (match_operand:HI 1 "general_operand" "R,Q")
+ (call (match_operand:HI 1 "general_operand" "rR,Q")
(match_operand:HI 2 "general_operand" "g,g")))
;; (use (reg:HI 0)) - what was that ????
]
"")
(define_insn ""
- [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 4)
+ [(set (subreg:HI (match_operand:SI 0 "general_operand" "=r") 2)
(mod:HI (match_operand:SI 1 "general_operand" "0")
(match_operand:HI 2 "general_operand" "g")))]
"TARGET_45"