diff -urN gcc-3.2/ChangeLog gcc-3.2-pdp11port/ChangeLog --- gcc-3.2/ChangeLog Wed Aug 14 17:58:56 2002 +++ gcc-3.2-pdp11port/ChangeLog Sat Oct 5 01:41:51 2002 @@ -1,3 +1,39 @@ +2002-10-05 Naohiko Shimizu + * t-pdp11: add MULTILIB support for msoft-float and mint32 + * pdp11.h (LEGITIMATE_CONSTANT_P): fix soft-float case. +2002-09-13 Naohiko Shimizu + * t-pdp11: add LIB2FUNCS_EXTRA + * pdp11.c (pdp11_output_function_prologue): restrict offset to 16bit, + add preceding 0 to the octal constant, + rename 'fp' to 'r5', rename 'fldd' to 'ldd', + rename 'fstd' to 'std' + (pdp11_output_function_epilogue): same as. + (output_move_quad): make the comment gas compatible + (output_ascii): add preceding 0 to the octal constant + (print_operand_address): add pre_modify, post_modify + (output_addr_const_pdp11): add preceding 0 to the octal constant + * pdp11.h (GO_IF_LEGITIMATE_ADDRESS) : add 'movb' pre_modify case + with the indication of Paul Koning. + (PRINT_OPERAND): fix floating constant. + * pdp11.md (movdi): restrict matching pattern + (movqi): generalize the matching pattern + (movdf): restrict matching pattern + (zero_extendqihi2): change constant representation + (floatsidf2): fix wrong operands + (addqi3): fix wrong instruction name + (subqi3): fix wrong instruction name + (andsi3): simplify and fix to use 'bic' + (andhi3): same as. + (andqi3): same as + (xorsi3): fix wrong insn + (one_cmplqi2): add two operand pattern(not required) + (lsrsi3): new + (negsi2): new + (call): add register indirect case + (mod): fix wrong subreg + + configure --target=pdp11-none-aout --with-included-gettext is used. + 2002-08-14 Release Manager * GCC 3.2 Released. diff -urN gcc-3.2/gcc/config/pdp11/pdp11-lib2.c gcc-3.2-pdp11port/gcc/config/pdp11/pdp11-lib2.c --- gcc-3.2/gcc/config/pdp11/pdp11-lib2.c Thu Jan 1 09:00:00 1970 +++ gcc-3.2-pdp11port/gcc/config/pdp11/pdp11-lib2.c Sat Feb 1 17:37:32 2003 @@ -0,0 +1,165 @@ +typedef int HItype __attribute__ ((mode (HI))); +typedef int SItype __attribute__ ((mode (SI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); + +typedef int word_type __attribute__ ((mode (__word__))); + +USItype +udivmodsi4(USItype num, USItype den, word_type modwanted) +{ + USItype bit = 1; + USItype res = 0; + + while (den < num && bit && !(den & (1L<<31))) + { + den <<=1; + bit <<=1; + } + while (bit) + { + if (num >= den) + { + num -= den; + res |= bit; + } + bit >>=1; + den >>=1; + } + if (modwanted) return num; + return res; +} + + + +SItype +__divsi3 (SItype a, SItype b) +{ + word_type neg = 0; + SItype res; + + if (a < 0) + { + a = -a; + neg = !neg; + } + + if (b < 0) + { + b = -b; + neg = !neg; + } + + res = udivmodsi4 (a, b, 0); + + if (neg) + res = -res; + + return res; +} + + + +SItype +__modsi3 (SItype a, SItype b) +{ + word_type neg = 0; + SItype res; + + if (a < 0) + { + a = -a; + neg = 1; + } + + if (b < 0) + b = -b; + + res = udivmodsi4 (a, b, 1); + + if (neg) + res = -res; + + return res; +} + + + + +SItype +__udivsi3 (SItype a, SItype b) +{ + return udivmodsi4 (a, b, 0); +} + + + +SItype +__umodsi3 (SItype a, SItype b) +{ + return udivmodsi4 (a, b, 1); +} + +SItype +__ashlsi3 (SItype a, SItype b) +{ + word_type i; + + for (i = b; i > 0; --i) + a <<= 1; + return a; +} + +SItype +__ashrsi3 (SItype a, SItype b) +{ + word_type i; + + for (i = b; i > 0; --i) + a >>= 1; + return a; +} + +USItype +__lshrsi3 (USItype a, USItype b) +{ + word_type i; + + for (i = b; i > 0; --i) + a >>= 1; + return a; +} + +USItype +__xorsi3 (USItype a, USItype b) +{ + word_type i; + + return a&~b | ~a&b; +} + +USItype +umulsi3 (USItype a, USItype b) +{ + word_type i; + USItype pp; + for(i=0; i<32; i++) { + pp=a*(b&1); + b>>=1; + a<<=1; + } + return pp; +} + +SItype +__mulsi3 (SItype a, SItype b) +{ + word_type i,nega,negb; + SItype res; + + if(a<0) {nega=1; a=-a;} else nega=0; + if(b<0) {negb=1; b=-b;} else negb=0; + + return (1-2*(nega^negb))*(SItype)umulsi3((USItype)a,(USItype)b); +} + + diff -urN gcc-3.2/gcc/config/pdp11/pdp11.c gcc-3.2-pdp11port/gcc/config/pdp11/pdp11.c --- gcc-3.2/gcc/config/pdp11/pdp11.c Tue Dec 18 00:05:36 2001 +++ gcc-3.2-pdp11port/gcc/config/pdp11/pdp11.c Fri Jun 20 15:24:15 2003 @@ -137,13 +137,51 @@ { fprintf (stream, "\t/*abuse empty parameter slot for locals!*/\n"); if (size > 2) - fprintf(stream, "\tsub $%d, sp\n", size - 2); + fprintf(stream, "\tsub $%#o, sp\n", size - 2); } } #else /* !TWO_BSD */ +#ifdef ELIMINABLE_REGS +int initial_offset (int from, int to) +{ + int regno, offset=0; + + /* The difference between the argument pointer and the frame pointer + * is the size of the callee register save area. */ + if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM) + { + return 0; + } + /* The difference between the argument pointer and the stack pointer is + * the sum of the size of this function's frame, the callee register save + * area, and the fixed stack space needed for function calls (if any). */ + + for (regno = 0; regno < 8; regno++) + if (regs_ever_live[regno] && ! call_used_regs[regno]) + offset += 2; + for (regno = 8; regno < 14; regno++) + if (regs_ever_live[regno] && ! call_used_regs[regno]) + offset += 8; + if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM) + { + offset = (get_frame_size () + offset -2); + return offset; + } + + /* The difference between the frame pointer and stack pointer is the sum + * of the size of this function's frame and the fixed stack space needed + * for function calls (if any). */ + if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM) + return get_frame_size (); + + abort (); +} +#endif + + static void pdp11_output_function_prologue (stream, size) FILE *stream; @@ -168,8 +206,8 @@ 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 { @@ -178,7 +216,7 @@ /* make frame */ if (fsize) - fprintf (stream, "\tsub $%o, sp\n", fsize); + fprintf (stream, "\tsub $%#o, sp\n", fsize); /* save CPU registers */ for (regno = 0; regno < 8; regno++) @@ -198,7 +236,7 @@ && 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; } @@ -211,8 +249,8 @@ 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]); } } @@ -277,9 +315,10 @@ /* 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 %#o(r5), %s\n",(-fsize-2*j--)&0xffff, reg_names[i]); /* get ACs */ via_ac = FIRST_PSEUDO_REGISTER -1; @@ -297,7 +336,7 @@ && regs_ever_live[i] && ! call_used_regs[i]) { - fprintf(stream, "\tfldd %o(fp), %s\n", -fsize-k, reg_names[i]); + fprintf(stream, "\tldd %#o(r5), %s\n", (-fsize-k)&0xffff, reg_names[i]); k -= 8; } @@ -308,14 +347,14 @@ 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 %#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 { @@ -331,7 +370,7 @@ 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] @@ -340,8 +379,8 @@ 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]); } } @@ -350,7 +389,7 @@ fprintf(stream, "\tmov (sp)+, %s\n", reg_names[i]); if (fsize) - fprintf((stream), "\tadd $%o, sp\n", fsize); + fprintf((stream), "\tadd $%#o, sp\n", (fsize)&0xffff); } fprintf (stream, "\trts pc\n"); @@ -561,7 +600,7 @@ 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; @@ -817,7 +856,7 @@ register int c = p[i]; if (c < 0) c += 256; - fprintf (file, "%o", c); + fprintf (file, "%#o", c); if (i < size - 1) putc (',', file); } @@ -851,10 +890,12 @@ 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; @@ -1546,7 +1587,7 @@ 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, "%#ho", (unsigned short) INTVAL (x)); break; case CONST: @@ -1562,7 +1603,7 @@ 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, "%#ho", (unsigned short) CONST_DOUBLE_LOW (x)); } else /* We can't handle floating point constants; diff -urN gcc-3.2/gcc/config/pdp11/pdp11.h gcc-3.2-pdp11port/gcc/config/pdp11/pdp11.h --- gcc-3.2/gcc/config/pdp11/pdp11.h Wed Jan 16 11:37:32 2002 +++ gcc-3.2-pdp11port/gcc/config/pdp11/pdp11.h Fri Jun 20 11:09:05 2003 @@ -20,6 +20,7 @@ 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) @@ -221,7 +222,7 @@ we have 8 integer registers, plus 6 float (don't use scratch float !) */ -#define FIRST_PSEUDO_REGISTER 14 +#define FIRST_PSEUDO_REGISTER 15 /* 1 for registers that have pervasive standard uses and are not available for the register allocator. @@ -236,7 +237,7 @@ #define FIXED_REGISTERS \ {0, 0, 0, 0, 0, 0, 1, 1, \ - 0, 0, 0, 0, 0, 0 } + 0, 0, 0, 0, 0, 0, 1 } @@ -250,7 +251,7 @@ /* don't know about fp */ #define CALL_USED_REGISTERS \ {1, 1, 0, 0, 0, 0, 1, 1, \ - 0, 0, 0, 0, 0, 0 } + 0, 0, 0, 0, 0, 0, 1 } /* Make sure everything's fine if we *don't* have an FPU. @@ -336,7 +337,7 @@ #define FRAME_POINTER_REQUIRED 0 /* Base register for access to arguments of the function. */ -#define ARG_POINTER_REGNUM 5 +#define ARG_POINTER_REGNUM 14 /* Register in which static-chain is passed to a function. */ /* ??? - i don't want to give up a reg for this! */ @@ -666,18 +667,22 @@ #define INITIAL_FRAME_POINTER_OFFSET(DEPTH_VAR) \ { \ - int offset, regno; \ - offset = get_frame_size(); \ - for (regno = 0; regno < 8; regno++) \ - if (regs_ever_live[regno] && ! call_used_regs[regno]) \ - offset += 2; \ - for (regno = 8; regno < 14; regno++) \ - if (regs_ever_live[regno] && ! call_used_regs[regno]) \ - offset += 8; \ - /* offset -= 2; no fp on stack frame */ \ - (DEPTH_VAR) = offset; \ -} - + DEPTH_VAR = initial_offset (reg_eliminate); \ +} +#if 1 +#define ELIMINABLE_REGS \ +{{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ + {ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \ + {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}} + +#define CAN_ELIMINATE(FROM, TO) \ + (TO == STACK_POINTER_REGNUM && \ + frame_pointer_needed)?0:1 + +#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ + OFFSET = initial_offset (FROM, TO) +#endif + /* Addressing modes, and classification of registers for them. */ @@ -717,7 +722,7 @@ /* 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. @@ -788,6 +793,29 @@ && 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) \ @@ -806,11 +834,6 @@ if (GET_MODE_BITSIZE(mode) > 16) \ goto fail; \ \ - /* accept @(R0) - which is @0(R0) */ \ - if (GET_CODE (xfoob) == REG \ - && REG_OK_FOR_BASE_P(xfoob)) \ - goto ADDR; \ - \ /* accept @address */ \ if (CONSTANT_ADDRESS_P (xfoob)) \ goto ADDR; \ @@ -1113,7 +1136,7 @@ } #define ASM_OUTPUT_SKIP(FILE,SIZE) \ - fprintf (FILE, "\t.=.+ %o\n", (SIZE)) + fprintf (FILE, "\t.=.+ %#o\n", (SIZE)) /* This says how to output an assembler line to define a global common symbol. */ @@ -1123,7 +1146,7 @@ assemble_name ((FILE), (NAME)), \ fprintf ((FILE), "\n"), \ assemble_name ((FILE), (NAME)), \ - fprintf ((FILE), ": .=.+ %o\n", (ROUNDED)) \ + fprintf ((FILE), ": .=.+ %#o\n", (ROUNDED)) \ ) /* This says how to output an assembler line @@ -1131,7 +1154,7 @@ #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \ ( assemble_name ((FILE), (NAME)), \ - fprintf ((FILE), ":\t.=.+ %o\n", (ROUNDED))) + fprintf ((FILE), ":\t.=.+ %#o\n", (ROUNDED))) /* Store in OUTPUT a string (made with alloca) containing an assembler-name for a local static variable named NAME. @@ -1157,7 +1180,7 @@ else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) != SImode) \ { union { double d; int i[2]; } u; \ u.i[0] = CONST_DOUBLE_LOW (X); u.i[1] = CONST_DOUBLE_HIGH (X); \ - fprintf (FILE, "#%.20e", u.d); } \ + fprintf (FILE, "$0F%.20e", u.d); } \ else { putc ('$', FILE); output_addr_const_pdp11 (FILE, X); }} /* Print a memory address as an operand to reference that memory location. */ diff -urN gcc-3.2/gcc/config/pdp11/pdp11.md gcc-3.2-pdp11port/gcc/config/pdp11/pdp11.md --- gcc-3.2/gcc/config/pdp11/pdp11.md Sun Nov 4 11:12:13 2001 +++ gcc-3.2-pdp11port/gcc/config/pdp11/pdp11.md Fri Jun 20 22:56:31 2003 @@ -621,12 +621,12 @@ ;; 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 "nonimmediate_operand" "=g,m,o") + (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") @@ -651,8 +651,8 @@ [(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"))] "" "* { @@ -661,17 +661,22 @@ 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") @@ -760,7 +765,7 @@ [(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" @@ -874,8 +879,8 @@ (define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (sign_extend:SI (match_operand:HI 1 "general_operand" "0")))] + [(set (match_operand:SI 0 "register_operand" "=r,r") + (sign_extend:SI (match_operand:HI 1 "general_operand" "0,g")))] "(! TARGET_40_PLUS)" "* { @@ -886,10 +891,14 @@ lateoperands[0] = operands[0]; operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1); + if (which_alternative ==1) { + output_asm_insn(\"mov %1, %0\", operands); + } + output_asm_insn(\"tst %0\", operands); sprintf(buf, \"bge extendhisi%d\", count); output_asm_insn(buf, NULL); - output_asm_insn(\"mov -1, %0\", lateoperands); + output_asm_insn(\"mov $-1, %0\", lateoperands); sprintf(buf, \"bne extendhisi%d\", count+1); output_asm_insn(buf, NULL); sprintf(buf, \"\\nextendhisi%d:\", count); @@ -902,7 +911,7 @@ return \"\"; }" - [(set_attr "length" "6")]) + [(set_attr "length" "6,8")]) ;; make float to int and vice versa ;; using the cc_status.flag field we could probably cut down @@ -919,7 +928,7 @@ 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); @@ -1067,7 +1076,7 @@ return \"decb %0\"; } - return \"addb %2, %0\"; + return \"add %2, %0\"; }" [(set_attr "length" "1,2,2,3")]) @@ -1143,7 +1152,7 @@ if (GET_CODE (operands[2]) == CONST_INT) abort(); - return \"subb %2, %0\"; + return \"sub %2, %0\"; }" [(set_attr "length" "1,2,2,3")]) @@ -1151,8 +1160,8 @@ ;; 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"))))] + (and:SI (match_operand:SI 1 "general_operand" "0") + (not:SI (match_operand:SI 2 "general_operand" "g"))))] "" " { @@ -1164,8 +1173,8 @@ (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"))))] + (and:HI (match_operand:HI 1 "general_operand" "0") + (not:HI (match_operand:HI 2 "general_operand" "g"))))] "" " { @@ -1174,22 +1183,22 @@ 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"))))] + (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)); + operands[2] = GEN_INT (~INTVAL (op)); else operands[2] = expand_unop (QImode, one_cmpl_optab, op, 0, 1); }") -(define_insn "andcbsi3" + +(define_insn "" [(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"))))] @@ -1237,7 +1246,7 @@ }" [(set_attr "length" "2,4,4,6,2,2,4,3,3,6")]) -(define_insn "andcbhi3" +(define_insn "" [(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"))))] @@ -1245,12 +1254,18 @@ "bic %2, %0" [(set_attr "length" "1,2,2,3")]) -(define_insn "andcbqi3" +(define_insn "" [(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"))))] "" - "bicb %2, %0" + "* +{ + if ( CONSTANT_P(operands[2])) + operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff); + output_asm_insn (\"bicb %2, %0\", operands); + return \"\"; +}" [(set_attr "length" "1,2,2,3")]) ;;- Bit set (inclusive or) instructions @@ -1319,9 +1334,9 @@ ;;- 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 */ @@ -1342,18 +1357,8 @@ 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") @@ -1373,10 +1378,12 @@ [(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 @@ -1388,12 +1395,52 @@ "ashc %2,%0" [(set_attr "length" "1,2")]) +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=r") + (ashift:SI (match_operand:SI 1 "register_operand" "0") + (const_int 1)))] + "!TARGET_45" + "* + { + + rtx lateoperands[2]; + + lateoperands[0] = operands[0]; + operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1); + + output_asm_insn (\"asl %0\", operands); + output_asm_insn (\"rol %0\", lateoperands); + + return \"\"; + }" + [(set_attr "length" "2")]) + +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=r") + (ashift:SI (match_operand:SI 1 "register_operand" "0") + (const_int -1)))] + "!TARGET_45" + "* + { + + rtx lateoperands[2]; + + lateoperands[0] = operands[0]; + operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1); + + output_asm_insn (\"asr %0\", lateoperands); + output_asm_insn (\"ror %0\", operands); + + return \"\"; + }" + [(set_attr "length" "2")]) + ;; Arithmetic right shift on the pdp works by negating the shift count. (define_expand "ashrsi3" [(set (match_operand:SI 0 "register_operand" "=r") (ashift:SI (match_operand:SI 1 "register_operand" "0") (match_operand:HI 2 "general_operand" "g")))] - "" + "TARGET_45" " { operands[2] = negate_rtx (HImode, operands[2]); @@ -1423,6 +1470,38 @@ "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)))] + "" +{ + + 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 @@ -1430,7 +1509,7 @@ [(set (match_operand:HI 0 "general_operand" "=r") (ashift:HI (match_operand:HI 1 "general_operand" "0") (match_operand:HI 2 "expand_shift_operand" "O")))] - "! optimize_size" + "" "* { register int i; @@ -1512,10 +1591,12 @@ (define_insn "ashlhi3" [(set (match_operand:HI 0 "register_operand" "=r,r") (ashift:HI (match_operand:HI 1 "register_operand" "0,0") - (match_operand:HI 2 "general_operand" "rR,Qi")))] + (match_operand:HI 2 "general_operand" "+&rR,Qi")))] "" "* { + static int count = 0; + char buf[200]; if (GET_CODE(operands[2]) == CONST_INT) { if (INTVAL(operands[2]) == 1) @@ -1524,21 +1605,87 @@ return \"asr %0\"; } - return \"ash %2,%0\"; + if(TARGET_40_PLUS) return \"ash %2,%0\"; + else { + output_asm_insn(\"tst %2\", operands); + sprintf(buf, \"\\nash%d:\", count); + output_asm_insn(buf, NULL); + sprintf(buf, \"beq ashexit%d\", count); + output_asm_insn(buf, NULL); + sprintf(buf, \"bge ashp%d\", count); + output_asm_insn(buf, NULL); + output_asm_insn(\"asr %0\", operands); + output_asm_insn(\"inc %2\", operands); + sprintf(buf, \"br ash%d\", count); + output_asm_insn(buf, NULL); + sprintf(buf, \"\\nashp%d:\", count); + output_asm_insn(buf, NULL); + output_asm_insn(\"asl %0\", operands); + output_asm_insn(\"dec %2\", operands); + sprintf(buf, \"br ash%d\", count); + output_asm_insn(buf, NULL); + sprintf(buf, \"\\nashexit%d:\", count++); + output_asm_insn(buf, NULL); + + return \"\"; + } }" [(set_attr "length" "1,2")]) + +(define_insn "" + [(set (match_operand:HI 0 "register_operand" "=r") + (ashift:HI (match_operand:HI 1 "register_operand" "0") + (const_int 1)))] + "" + "* +{ + return \"asl %0\"; +}" + [(set_attr "length" "1")]) + +(define_insn "" + [(set (match_operand:HI 0 "register_operand" "=r") + (ashift:HI (match_operand:HI 1 "register_operand" "0") + (const_int -1)))] + "" + "* +{ + return \"asr %0\"; +}" + [(set_attr "length" "1")]) + ;; Arithmetic right shift on the pdp works by negating the shift count. (define_expand "ashrhi3" [(set (match_operand:HI 0 "register_operand" "=r") (ashift:HI (match_operand:HI 1 "register_operand" "0") - (match_operand:HI 2 "general_operand" "g")))] + (match_operand:HI 2 "const_int_operand" "i")))] "" " { + if (GET_CODE (operands[2]) != CONST_INT + || abs(INTVAL (operands[2])) > 4 ) + FAIL; operands[2] = negate_rtx (HImode, operands[2]); }") +(define_insn "" + [(set (match_operand:HI 0 "register_operand" "=r") + (ashift:HI (match_operand:HI 1 "register_operand" "0") + (match_operand:HI 2 "const_int_operand" "i")))] + "" + "* +{ + register int i; + + for (i = 1; i <= abs(INTVAL(operands[2])); i++) + output_asm_insn(\"asr %0\", operands); + + return \"\"; +}" + [(set_attr "length" "4")]) + + ;;;;- logical shift instructions ;;(define_insn "lshrsi3" ;; [(set (match_operand:HI 0 "register_operand" "=r") @@ -1620,6 +1767,29 @@ "{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")))] + "" +{ + + 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")))] @@ -1670,7 +1840,7 @@ ;;- 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 ??? ] @@ -1682,7 +1852,7 @@ ;;- 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 ???? ] @@ -1788,7 +1958,7 @@ "") (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" diff -urN gcc-3.2/gcc/config/pdp11/t-pdp11 gcc-3.2-pdp11port/gcc/config/pdp11/t-pdp11 --- gcc-3.2/gcc/config/pdp11/t-pdp11 Thu May 17 12:16:09 2001 +++ gcc-3.2-pdp11port/gcc/config/pdp11/t-pdp11 Mon Oct 21 17:12:32 2002 @@ -1 +1,16 @@ TARGET_LIBGCC2_CFLAGS = -O2 -mfloat32 +LIB2FUNCS_EXTRA = $(srcdir)/config/udivmod.c $(srcdir)/config/udivmodsi4.c \ + $(srcdir)/config/pdp11/pdp11-lib2.c +# floating point emulation libraries + +FPBIT = fp-bit.c +DPBIT = dp-bit.c + +fp-bit.c: $(srcdir)/config/fp-bit.c + echo '#define FLOAT' > fp-bit.c + cat $(srcdir)/config/fp-bit.c >> fp-bit.c + +dp-bit.c: $(srcdir)/config/fp-bit.c + cat $(srcdir)/config/fp-bit.c > dp-bit.c + +MULTILIB_OPTIONS = msoft-float m10