00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "config.h"
00024 #include "system.h"
00025 #include "coretypes.h"
00026 #include "tm.h"
00027 #include "rtl.h"
00028 #include "regs.h"
00029 #include "hard-reg-set.h"
00030 #include "real.h"
00031 #include "insn-config.h"
00032 #include "conditions.h"
00033 #include "function.h"
00034 #include "output.h"
00035 #include "insn-attr.h"
00036 #include "flags.h"
00037 #include "recog.h"
00038 #include "tree.h"
00039 #include "expr.h"
00040 #include "toplev.h"
00041 #include "tm_p.h"
00042 #include "target.h"
00043 #include "target-def.h"
00044
00045
00046
00047
00048
00049
00050
00051
00052 int current_first_parm_offset;
00053
00054
00055 static void encode_pdp11_f (const struct real_format *fmt,
00056 long *, const REAL_VALUE_TYPE *);
00057 static void decode_pdp11_f (const struct real_format *,
00058 REAL_VALUE_TYPE *, const long *);
00059 static void encode_pdp11_d (const struct real_format *fmt,
00060 long *, const REAL_VALUE_TYPE *);
00061 static void decode_pdp11_d (const struct real_format *,
00062 REAL_VALUE_TYPE *, const long *);
00063
00064
00065
00066 const struct real_format pdp11_f_format =
00067 {
00068 encode_pdp11_f,
00069 decode_pdp11_f,
00070 2,
00071 1,
00072 24,
00073 24,
00074 -127,
00075 127,
00076 15,
00077 false,
00078 false,
00079 false,
00080 false,
00081 false
00082 };
00083
00084 const struct real_format pdp11_d_format =
00085 {
00086 encode_pdp11_d,
00087 decode_pdp11_d,
00088 2,
00089 1,
00090 56,
00091 56,
00092 -127,
00093 127,
00094 15,
00095 false,
00096 false,
00097 false,
00098 false,
00099 false
00100 };
00101
00102 static void
00103 encode_pdp11_f (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
00104 const REAL_VALUE_TYPE *r)
00105 {
00106 (*vax_f_format.encode) (fmt, buf, r);
00107 buf[0] = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
00108 }
00109
00110 static void
00111 decode_pdp11_f (const struct real_format *fmt ATTRIBUTE_UNUSED,
00112 REAL_VALUE_TYPE *r, const long *buf)
00113 {
00114 long tbuf;
00115 tbuf = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
00116 (*vax_f_format.decode) (fmt, r, &tbuf);
00117 }
00118
00119 static void
00120 encode_pdp11_d (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
00121 const REAL_VALUE_TYPE *r)
00122 {
00123 (*vax_d_format.encode) (fmt, buf, r);
00124 buf[0] = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
00125 buf[1] = ((buf[1] >> 16) & 0xffff) | ((buf[1] & 0xffff) << 16);
00126 }
00127
00128 static void
00129 decode_pdp11_d (const struct real_format *fmt ATTRIBUTE_UNUSED,
00130 REAL_VALUE_TYPE *r, const long *buf)
00131 {
00132 long tbuf[2];
00133 tbuf[0] = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
00134 tbuf[1] = ((buf[1] >> 16) & 0xffff) | ((buf[1] & 0xffff) << 16);
00135 (*vax_d_format.decode) (fmt, r, tbuf);
00136 }
00137
00138
00139
00140
00141 static rtx find_addr_reg (rtx);
00142 static const char *singlemove_string (rtx *);
00143 static bool pdp11_assemble_integer (rtx, unsigned int, int);
00144 static void pdp11_output_function_prologue (FILE *, HOST_WIDE_INT);
00145 static void pdp11_output_function_epilogue (FILE *, HOST_WIDE_INT);
00146 static bool pdp11_rtx_costs (rtx, int, int, int *);
00147 static bool pdp11_return_in_memory (tree, tree);
00148
00149
00150 #undef TARGET_ASM_BYTE_OP
00151 #define TARGET_ASM_BYTE_OP NULL
00152 #undef TARGET_ASM_ALIGNED_HI_OP
00153 #define TARGET_ASM_ALIGNED_HI_OP NULL
00154 #undef TARGET_ASM_ALIGNED_SI_OP
00155 #define TARGET_ASM_ALIGNED_SI_OP NULL
00156 #undef TARGET_ASM_INTEGER
00157 #define TARGET_ASM_INTEGER pdp11_assemble_integer
00158
00159 #undef TARGET_ASM_FUNCTION_PROLOGUE
00160 #define TARGET_ASM_FUNCTION_PROLOGUE pdp11_output_function_prologue
00161 #undef TARGET_ASM_FUNCTION_EPILOGUE
00162 #define TARGET_ASM_FUNCTION_EPILOGUE pdp11_output_function_epilogue
00163
00164 #undef TARGET_ASM_OPEN_PAREN
00165 #define TARGET_ASM_OPEN_PAREN "["
00166 #undef TARGET_ASM_CLOSE_PAREN
00167 #define TARGET_ASM_CLOSE_PAREN "]"
00168
00169 #undef TARGET_RTX_COSTS
00170 #define TARGET_RTX_COSTS pdp11_rtx_costs
00171
00172 #undef TARGET_RETURN_IN_MEMORY
00173 #define TARGET_RETURN_IN_MEMORY pdp11_return_in_memory
00174
00175 struct gcc_target targetm = TARGET_INITIALIZER;
00176
00177
00178
00179 int
00180 arith_operand (rtx op, enum machine_mode mode)
00181 {
00182 return (register_operand (op, mode) || GET_CODE (op) == CONST_INT);
00183 }
00184
00185 int
00186 const_immediate_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
00187 {
00188 return (GET_CODE (op) == CONST_INT);
00189 }
00190
00191 int
00192 immediate15_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
00193 {
00194 return (GET_CODE (op) == CONST_INT && ((INTVAL (op) & 0x8000) == 0x0000));
00195 }
00196
00197 int
00198 expand_shift_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
00199 {
00200 return (GET_CODE (op) == CONST_INT
00201 && abs (INTVAL(op)) > 1
00202 && abs (INTVAL(op)) <= 4);
00203 }
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 #ifdef TWO_BSD
00215
00216 static void
00217 pdp11_output_function_prologue (FILE *stream, HOST_WIDE_INT size)
00218 {
00219 fprintf (stream, "\tjsr r5, csv\n");
00220 if (size)
00221 {
00222 fprintf (stream, "\t/*abuse empty parameter slot for locals!*/\n");
00223 if (size > 2)
00224 fprintf(stream, "\tsub $%#o, sp\n", size - 2);
00225
00226 }
00227 }
00228
00229 #else
00230
00231 static void
00232 pdp11_output_function_prologue (FILE *stream, HOST_WIDE_INT size)
00233 {
00234 HOST_WIDE_INT fsize = ((size) + 1) & ~1;
00235 int regno;
00236 int via_ac = -1;
00237
00238 fprintf (stream,
00239 "\n\t; /* function prologue %s*/\n",
00240 current_function_name ());
00241
00242
00243
00244 if (MAIN_NAME_P (DECL_NAME (current_function_decl)) && TARGET_FPU)
00245 {
00246 fprintf(stream,
00247 "\t;/* switch cpu to double float, single integer */\n");
00248 fprintf(stream, "\tsetd\n");
00249 fprintf(stream, "\tseti\n\n");
00250 }
00251
00252 if (frame_pointer_needed)
00253 {
00254 fprintf(stream, "\tmov r5, -(sp)\n");
00255 fprintf(stream, "\tmov sp, r5\n");
00256 }
00257 else
00258 {
00259
00260 }
00261
00262
00263 if (fsize)
00264 fprintf (stream, "\tsub $%#o, sp\n", fsize);
00265
00266
00267 for (regno = 0; regno < 8; regno++)
00268 if (regs_ever_live[regno] && ! call_used_regs[regno])
00269 if (! ((regno == FRAME_POINTER_REGNUM)
00270 && frame_pointer_needed))
00271 fprintf (stream, "\tmov %s, -(sp)\n", reg_names[regno]);
00272
00273
00274
00275 via_ac = -1;
00276
00277 for (regno = 8; regno < FIRST_PSEUDO_REGISTER ; regno++)
00278 {
00279
00280 if (LOAD_FPU_REG_P(regno)
00281 && regs_ever_live[regno]
00282 && ! call_used_regs[regno])
00283 {
00284 fprintf (stream, "\tstd %s, -(sp)\n", reg_names[regno]);
00285 via_ac = regno;
00286 }
00287
00288
00289
00290 if (NO_LOAD_FPU_REG_P(regno)
00291 && regs_ever_live[regno]
00292 && ! call_used_regs[regno])
00293 {
00294 if (via_ac == -1)
00295 abort();
00296
00297 fprintf (stream, "\tldd %s, %s\n", reg_names[regno], reg_names[via_ac]);
00298 fprintf (stream, "\tstd %s, -(sp)\n", reg_names[via_ac]);
00299 }
00300 }
00301
00302 fprintf (stream, "\t;/* end of prologue */\n\n");
00303 }
00304
00305 #endif
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 #ifdef TWO_BSD
00327
00328 static void
00329 pdp11_output_function_epilogue (FILE *stream,
00330 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
00331 {
00332 fprintf (stream, "\t/* SP ignored by cret? */\n");
00333 fprintf (stream, "\tjmp cret\n");
00334 }
00335
00336 #else
00337
00338 static void
00339 pdp11_output_function_epilogue (FILE *stream, HOST_WIDE_INT size)
00340 {
00341 HOST_WIDE_INT fsize = ((size) + 1) & ~1;
00342 int i, j, k;
00343
00344 int via_ac;
00345
00346 fprintf (stream, "\n\t; /*function epilogue */\n");
00347
00348 if (frame_pointer_needed)
00349 {
00350
00351 regs_ever_live[FRAME_POINTER_REGNUM] = 0;
00352
00353 for (i =7, j = 0 ; i >= 0 ; i--)
00354 if (regs_ever_live[i] && ! call_used_regs[i])
00355 j++;
00356
00357
00358 k = 2*j;
00359
00360
00361 for (i =7 ; i >= 0 ; i--)
00362 if (regs_ever_live[i] && ! call_used_regs[i])
00363 fprintf(stream, "\tmov %#o(r5), %s\n",(-fsize-2*j--)&0xffff, reg_names[i]);
00364
00365
00366 via_ac = FIRST_PSEUDO_REGISTER -1;
00367
00368 for (i = FIRST_PSEUDO_REGISTER; i > 7; i--)
00369 if (regs_ever_live[i] && ! call_used_regs[i])
00370 {
00371 via_ac = i;
00372 k += 8;
00373 }
00374
00375 for (i = FIRST_PSEUDO_REGISTER; i > 7; i--)
00376 {
00377 if (LOAD_FPU_REG_P(i)
00378 && regs_ever_live[i]
00379 && ! call_used_regs[i])
00380 {
00381 fprintf(stream, "\tldd %#o(r5), %s\n", (-fsize-k)&0xffff, reg_names[i]);
00382 k -= 8;
00383 }
00384
00385 if (NO_LOAD_FPU_REG_P(i)
00386 && regs_ever_live[i]
00387 && ! call_used_regs[i])
00388 {
00389 if (! LOAD_FPU_REG_P(via_ac))
00390 abort();
00391
00392 fprintf(stream, "\tldd %#o(r5), %s\n", (-fsize-k)&0xffff, reg_names[via_ac]);
00393 fprintf(stream, "\tstd %s, %s\n", reg_names[via_ac], reg_names[i]);
00394 k -= 8;
00395 }
00396 }
00397
00398 fprintf(stream, "\tmov r5, sp\n");
00399 fprintf (stream, "\tmov (sp)+, r5\n");
00400 }
00401 else
00402 {
00403 via_ac = FIRST_PSEUDO_REGISTER -1;
00404
00405
00406 for (i = FIRST_PSEUDO_REGISTER; i > 7; i--)
00407 if (regs_ever_live[i] && call_used_regs[i])
00408 via_ac = i;
00409
00410 for (i = FIRST_PSEUDO_REGISTER; i > 7; i--)
00411 {
00412 if (LOAD_FPU_REG_P(i)
00413 && regs_ever_live[i]
00414 && ! call_used_regs[i])
00415 fprintf(stream, "\tldd (sp)+, %s\n", reg_names[i]);
00416
00417 if (NO_LOAD_FPU_REG_P(i)
00418 && regs_ever_live[i]
00419 && ! call_used_regs[i])
00420 {
00421 if (! LOAD_FPU_REG_P(via_ac))
00422 abort();
00423
00424 fprintf(stream, "\tldd (sp)+, %s\n", reg_names[via_ac]);
00425 fprintf(stream, "\tstd %s, %s\n", reg_names[via_ac], reg_names[i]);
00426 }
00427 }
00428
00429 for (i=7; i >= 0; i--)
00430 if (regs_ever_live[i] && !call_used_regs[i])
00431 fprintf(stream, "\tmov (sp)+, %s\n", reg_names[i]);
00432
00433 if (fsize)
00434 fprintf((stream), "\tadd $%#o, sp\n", (fsize)&0xffff);
00435 }
00436
00437 fprintf (stream, "\trts pc\n");
00438 fprintf (stream, "\t;/* end of epilogue*/\n\n\n");
00439 }
00440
00441 #endif
00442
00443
00444
00445 static const char *
00446 singlemove_string (rtx *operands)
00447 {
00448 if (operands[1] != const0_rtx)
00449 return "mov %1,%0";
00450
00451 return "clr %0";
00452 }
00453
00454
00455
00456
00457
00458 const char *
00459 output_move_double (rtx *operands)
00460 {
00461 enum { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype0, optype1;
00462 rtx latehalf[2];
00463 rtx addreg0 = 0, addreg1 = 0;
00464
00465
00466
00467 if (REG_P (operands[0]))
00468 optype0 = REGOP;
00469 else if (offsettable_memref_p (operands[0]))
00470 optype0 = OFFSOP;
00471 else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
00472 optype0 = POPOP;
00473 else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
00474 optype0 = PUSHOP;
00475 else if (GET_CODE (operands[0]) == MEM)
00476 optype0 = MEMOP;
00477 else
00478 optype0 = RNDOP;
00479
00480 if (REG_P (operands[1]))
00481 optype1 = REGOP;
00482 else if (CONSTANT_P (operands[1])
00483 #if 0
00484 || GET_CODE (operands[1]) == CONST_DOUBLE
00485 #endif
00486 )
00487 optype1 = CNSTOP;
00488 else if (offsettable_memref_p (operands[1]))
00489 optype1 = OFFSOP;
00490 else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
00491 optype1 = POPOP;
00492 else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
00493 optype1 = PUSHOP;
00494 else if (GET_CODE (operands[1]) == MEM)
00495 optype1 = MEMOP;
00496 else
00497 optype1 = RNDOP;
00498
00499
00500
00501
00502
00503 if (optype0 == RNDOP || optype1 == RNDOP)
00504 abort ();
00505
00506
00507
00508
00509
00510 if (optype0 == PUSHOP && optype1 == POPOP)
00511 {
00512 operands[0] = XEXP (XEXP (operands[0], 0), 0);
00513 output_asm_insn ("sub $4,%0", operands);
00514 operands[0] = gen_rtx_MEM (SImode, operands[0]);
00515 optype0 = OFFSOP;
00516 }
00517 if (optype0 == POPOP && optype1 == PUSHOP)
00518 {
00519 operands[1] = XEXP (XEXP (operands[1], 0), 0);
00520 output_asm_insn ("sub $4,%1", operands);
00521 operands[1] = gen_rtx_MEM (SImode, operands[1]);
00522 optype1 = OFFSOP;
00523 }
00524
00525
00526
00527
00528 if (optype0 == MEMOP)
00529 addreg0 = find_addr_reg (XEXP (operands[0], 0));
00530
00531 if (optype1 == MEMOP)
00532 addreg1 = find_addr_reg (XEXP (operands[1], 0));
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543 if (optype0 == REGOP)
00544 latehalf[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
00545 else if (optype0 == OFFSOP)
00546 latehalf[0] = adjust_address (operands[0], HImode, 2);
00547 else
00548 latehalf[0] = operands[0];
00549
00550 if (optype1 == REGOP)
00551 latehalf[1] = gen_rtx_REG (HImode, REGNO (operands[1]) + 1);
00552 else if (optype1 == OFFSOP)
00553 latehalf[1] = adjust_address (operands[1], HImode, 2);
00554 else if (optype1 == CNSTOP)
00555 {
00556 if (CONSTANT_P (operands[1]))
00557 {
00558
00559
00560
00561 latehalf[1] = GEN_INT (INTVAL(operands[1]) >> 16);
00562 operands[1] = GEN_INT (INTVAL(operands[1]) & 0xff);
00563 }
00564 else if (GET_CODE (operands[1]) == CONST_DOUBLE)
00565 {
00566
00567 abort();
00568 }
00569 }
00570 else
00571 latehalf[1] = operands[1];
00572
00573
00574
00575
00576 if (optype0 == PUSHOP
00577 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
00578 && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
00579 operands[1] = latehalf[1];
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589 if (optype0 == PUSHOP || optype1 == PUSHOP
00590 || (optype0 == REGOP && optype1 == REGOP
00591 && REGNO (operands[0]) == REGNO (latehalf[1])))
00592 {
00593
00594 if (addreg0)
00595 output_asm_insn ("add $2,%0", &addreg0);
00596 if (addreg1)
00597 output_asm_insn ("add $2,%0", &addreg1);
00598
00599
00600 output_asm_insn (singlemove_string (latehalf), latehalf);
00601
00602
00603 if (addreg0)
00604 output_asm_insn ("sub $2,%0", &addreg0);
00605 if (addreg1)
00606 output_asm_insn ("sub $2,%0", &addreg1);
00607
00608
00609 return singlemove_string (operands);
00610 }
00611
00612
00613
00614 output_asm_insn (singlemove_string (operands), operands);
00615
00616
00617 if (addreg0)
00618 output_asm_insn ("add $2,%0", &addreg0);
00619 if (addreg1)
00620 output_asm_insn ("add $2,%0", &addreg1);
00621
00622
00623 output_asm_insn (singlemove_string (latehalf), latehalf);
00624
00625
00626 if (addreg0)
00627 output_asm_insn ("sub $2,%0", &addreg0);
00628 if (addreg1)
00629 output_asm_insn ("sub $2,%0", &addreg1);
00630
00631 return "";
00632 }
00633
00634
00635
00636 const char *
00637 output_move_quad (rtx *operands)
00638 {
00639 enum { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype0, optype1;
00640 rtx latehalf[2];
00641 rtx addreg0 = 0, addreg1 = 0;
00642
00643 output_asm_insn(";/* movdi/df: %1 -> %0 */", operands);
00644
00645 if (REG_P (operands[0]))
00646 optype0 = REGOP;
00647 else if (offsettable_memref_p (operands[0]))
00648 optype0 = OFFSOP;
00649 else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
00650 optype0 = POPOP;
00651 else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
00652 optype0 = PUSHOP;
00653 else if (GET_CODE (operands[0]) == MEM)
00654 optype0 = MEMOP;
00655 else
00656 optype0 = RNDOP;
00657
00658 if (REG_P (operands[1]))
00659 optype1 = REGOP;
00660 else if (CONSTANT_P (operands[1])
00661 || GET_CODE (operands[1]) == CONST_DOUBLE)
00662 optype1 = CNSTOP;
00663 else if (offsettable_memref_p (operands[1]))
00664 optype1 = OFFSOP;
00665 else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
00666 optype1 = POPOP;
00667 else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
00668 optype1 = PUSHOP;
00669 else if (GET_CODE (operands[1]) == MEM)
00670 optype1 = MEMOP;
00671 else
00672 optype1 = RNDOP;
00673
00674
00675
00676
00677
00678 if (optype0 == RNDOP || optype1 == RNDOP)
00679 abort ();
00680
00681
00682 if (optype0 == REGOP && optype1 == REGOP)
00683
00684 if (CPU_REG_P(REGNO(operands[0]))
00685 || CPU_REG_P (REGNO(operands[1])))
00686 abort();
00687
00688 if (optype0 == REGOP || optype1 == REGOP)
00689 {
00690
00691
00692
00693
00694
00695
00696
00697
00698 if (FPU_REG_P(REGNO(operands[0])))
00699 {
00700 if (GET_CODE(operands[1]) == CONST_DOUBLE)
00701 {
00702 REAL_VALUE_TYPE r;
00703 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
00704
00705 if (REAL_VALUES_EQUAL (r, dconst0))
00706 return "{clrd|clrf} %0";
00707 }
00708
00709 return "{ldd|movf} %1, %0";
00710 }
00711
00712 if (FPU_REG_P(REGNO(operands[1])))
00713 return "{std|movf} %1, %0";
00714 }
00715
00716
00717
00718
00719
00720 if (optype0 == PUSHOP && optype1 == POPOP)
00721 {
00722 operands[0] = XEXP (XEXP (operands[0], 0), 0);
00723 output_asm_insn ("sub $8,%0", operands);
00724 operands[0] = gen_rtx_MEM (DImode, operands[0]);
00725 optype0 = OFFSOP;
00726 }
00727 if (optype0 == POPOP && optype1 == PUSHOP)
00728 {
00729 operands[1] = XEXP (XEXP (operands[1], 0), 0);
00730 output_asm_insn ("sub $8,%1", operands);
00731 operands[1] = gen_rtx_MEM (SImode, operands[1]);
00732 optype1 = OFFSOP;
00733 }
00734
00735
00736
00737
00738 if (optype0 == MEMOP)
00739 addreg0 = find_addr_reg (XEXP (operands[0], 0));
00740
00741 if (optype1 == MEMOP)
00742 addreg1 = find_addr_reg (XEXP (operands[1], 0));
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753 if (optype0 == REGOP)
00754 latehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 2);
00755 else if (optype0 == OFFSOP)
00756 latehalf[0] = adjust_address (operands[0], SImode, 4);
00757 else
00758 latehalf[0] = operands[0];
00759
00760 if (optype1 == REGOP)
00761 latehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 2);
00762 else if (optype1 == OFFSOP)
00763 latehalf[1] = adjust_address (operands[1], SImode, 4);
00764 else if (optype1 == CNSTOP)
00765 {
00766 if (GET_CODE (operands[1]) == CONST_DOUBLE)
00767 {
00768 REAL_VALUE_TYPE r;
00769 long dval[2];
00770 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
00771 REAL_VALUE_TO_TARGET_DOUBLE (r, dval);
00772 latehalf[1] = GEN_INT (dval[1]);
00773 operands[1] = GEN_INT (dval[0]);
00774 }
00775 else if (GET_CODE(operands[1]) == CONST_INT)
00776 {
00777 latehalf[1] = const0_rtx;
00778 }
00779 else
00780 abort();
00781 }
00782 else
00783 latehalf[1] = operands[1];
00784
00785
00786
00787
00788 if (optype0 == PUSHOP
00789 && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
00790 && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
00791 operands[1] = latehalf[1];
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801 if (optype0 == PUSHOP || optype1 == PUSHOP
00802 || (optype0 == REGOP && optype1 == REGOP
00803 && REGNO (operands[0]) == REGNO (latehalf[1])))
00804 {
00805
00806 if (addreg0)
00807 output_asm_insn ("add $4,%0", &addreg0);
00808 if (addreg1)
00809 output_asm_insn ("add $4,%0", &addreg1);
00810
00811
00812 output_asm_insn(output_move_double(latehalf), latehalf);
00813
00814
00815 if (addreg0)
00816 output_asm_insn ("sub $4,%0", &addreg0);
00817 if (addreg1)
00818 output_asm_insn ("sub $4,%0", &addreg1);
00819
00820
00821 return output_move_double (operands);
00822 }
00823
00824
00825
00826 output_asm_insn (output_move_double (operands), operands);
00827
00828
00829 if (addreg0)
00830 output_asm_insn ("add $4,%0", &addreg0);
00831 if (addreg1)
00832 output_asm_insn ("add $4,%0", &addreg1);
00833
00834
00835 output_asm_insn (output_move_double (latehalf), latehalf);
00836
00837
00838 if (addreg0)
00839 output_asm_insn ("sub $4,%0", &addreg0);
00840 if (addreg1)
00841 output_asm_insn ("sub $4,%0", &addreg1);
00842
00843 return "";
00844 }
00845
00846
00847
00848
00849
00850 static rtx
00851 find_addr_reg (rtx addr)
00852 {
00853 while (GET_CODE (addr) == PLUS)
00854 {
00855 if (GET_CODE (XEXP (addr, 0)) == REG)
00856 addr = XEXP (addr, 0);
00857 if (GET_CODE (XEXP (addr, 1)) == REG)
00858 addr = XEXP (addr, 1);
00859 if (CONSTANT_P (XEXP (addr, 0)))
00860 addr = XEXP (addr, 1);
00861 if (CONSTANT_P (XEXP (addr, 1)))
00862 addr = XEXP (addr, 0);
00863 }
00864 if (GET_CODE (addr) == REG)
00865 return addr;
00866 return 0;
00867 }
00868
00869
00870 void
00871 output_ascii (FILE *file, const char *p, int size)
00872 {
00873 int i;
00874
00875
00876
00877 fprintf (file, "\t.byte ");
00878
00879 for (i = 0; i < size; i++)
00880 {
00881 register int c = p[i];
00882 if (c < 0)
00883 c += 256;
00884 fprintf (file, "%#o", c);
00885 if (i < size - 1)
00886 putc (',', file);
00887 }
00888 putc ('\n', file);
00889 }
00890
00891
00892
00893
00894 void
00895 print_operand_address (FILE *file, register rtx addr)
00896 {
00897 register rtx reg1, reg2, breg, ireg;
00898 rtx offset;
00899
00900 retry:
00901
00902 switch (GET_CODE (addr))
00903 {
00904 case MEM:
00905 if (TARGET_UNIX_ASM)
00906 fprintf (file, "*");
00907 else
00908 fprintf (file, "@");
00909 addr = XEXP (addr, 0);
00910 goto retry;
00911
00912 case REG:
00913 fprintf (file, "(%s)", reg_names[REGNO (addr)]);
00914 break;
00915
00916 case PRE_MODIFY:
00917 case PRE_DEC:
00918 fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
00919 break;
00920
00921 case POST_MODIFY:
00922 case POST_INC:
00923 fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
00924 break;
00925
00926 case PLUS:
00927 reg1 = 0; reg2 = 0;
00928 ireg = 0; breg = 0;
00929 offset = 0;
00930 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
00931 || GET_CODE (XEXP (addr, 0)) == MEM)
00932 {
00933 offset = XEXP (addr, 0);
00934 addr = XEXP (addr, 1);
00935 }
00936 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
00937 || GET_CODE (XEXP (addr, 1)) == MEM)
00938 {
00939 offset = XEXP (addr, 1);
00940 addr = XEXP (addr, 0);
00941 }
00942 if (GET_CODE (addr) != PLUS)
00943 ;
00944 else if (GET_CODE (XEXP (addr, 0)) == MULT)
00945 {
00946 reg1 = XEXP (addr, 0);
00947 addr = XEXP (addr, 1);
00948 }
00949 else if (GET_CODE (XEXP (addr, 1)) == MULT)
00950 {
00951 reg1 = XEXP (addr, 1);
00952 addr = XEXP (addr, 0);
00953 }
00954 else if (GET_CODE (XEXP (addr, 0)) == REG)
00955 {
00956 reg1 = XEXP (addr, 0);
00957 addr = XEXP (addr, 1);
00958 }
00959 else if (GET_CODE (XEXP (addr, 1)) == REG)
00960 {
00961 reg1 = XEXP (addr, 1);
00962 addr = XEXP (addr, 0);
00963 }
00964 if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT)
00965 {
00966 if (reg1 == 0)
00967 reg1 = addr;
00968 else
00969 reg2 = addr;
00970 addr = 0;
00971 }
00972 if (offset != 0)
00973 {
00974 if (addr != 0) abort ();
00975 addr = offset;
00976 }
00977 if (reg1 != 0 && GET_CODE (reg1) == MULT)
00978 {
00979 breg = reg2;
00980 ireg = reg1;
00981 }
00982 else if (reg2 != 0 && GET_CODE (reg2) == MULT)
00983 {
00984 breg = reg1;
00985 ireg = reg2;
00986 }
00987 else if (reg2 != 0 || GET_CODE (addr) == MEM)
00988 {
00989 breg = reg2;
00990 ireg = reg1;
00991 }
00992 else
00993 {
00994 breg = reg1;
00995 ireg = reg2;
00996 }
00997 if (addr != 0)
00998 output_address (addr);
00999 if (breg != 0)
01000 {
01001 if (GET_CODE (breg) != REG)
01002 abort ();
01003 fprintf (file, "(%s)", reg_names[REGNO (breg)]);
01004 }
01005 if (ireg != 0)
01006 {
01007 if (GET_CODE (ireg) == MULT)
01008 ireg = XEXP (ireg, 0);
01009 if (GET_CODE (ireg) != REG)
01010 abort ();
01011 abort();
01012 fprintf (file, "[%s]", reg_names[REGNO (ireg)]);
01013 }
01014 break;
01015
01016 default:
01017 output_addr_const_pdp11 (file, addr);
01018 }
01019 }
01020
01021
01022
01023
01024 static bool
01025 pdp11_assemble_integer (rtx x, unsigned int size, int aligned_p)
01026 {
01027 if (aligned_p)
01028 switch (size)
01029 {
01030 case 1:
01031 fprintf (asm_out_file, "\t.byte\t");
01032 output_addr_const_pdp11 (asm_out_file, x);
01033 fprintf (asm_out_file, " /* char */\n");
01034 return true;
01035
01036 case 2:
01037 fprintf (asm_out_file, TARGET_UNIX_ASM ? "\t" : "\t.word\t");
01038 output_addr_const_pdp11 (asm_out_file, x);
01039 fprintf (asm_out_file, " /* short */\n");
01040 return true;
01041 }
01042 return default_assemble_integer (x, size, aligned_p);
01043 }
01044
01045
01046
01047
01048 static const int move_costs[N_REG_CLASSES][N_REG_CLASSES] =
01049 {
01050
01051
01052 { 0, 0, 0, 0, 0, 0, 0},
01053 { 0, 2, 2, 10, 22, 22, 22},
01054 { 0, 2, 2, 10, 22, 22, 22},
01055 { 0, 10, 10, 2, 2, 2, 10},
01056 { 0, 22, 22, 2, 2, 2, 22},
01057 { 0, 22, 22, 2, 2, 2, 22},
01058 { 0, 22, 22, 10, 22, 22, 22}
01059 } ;
01060
01061
01062
01063
01064
01065
01066
01067 int
01068 register_move_cost(c1, c2)
01069 enum reg_class c1, c2;
01070 {
01071 return move_costs[(int)c1][(int)c2];
01072 }
01073
01074 static bool
01075 pdp11_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int *total)
01076 {
01077 switch (code)
01078 {
01079 case CONST_INT:
01080 if (INTVAL (x) == 0 || INTVAL (x) == -1 || INTVAL (x) == 1)
01081 {
01082 *total = 0;
01083 return true;
01084 }
01085
01086
01087 case CONST:
01088 case LABEL_REF:
01089 case SYMBOL_REF:
01090
01091 *total = 2;
01092 return true;
01093
01094 case CONST_DOUBLE:
01095
01096 *total = 4;
01097 return true;
01098
01099 case MULT:
01100
01101
01102
01103
01104 if (optimize_size)
01105 *total = COSTS_N_INSNS (2);
01106 else
01107 *total = COSTS_N_INSNS (11);
01108 return false;
01109
01110 case DIV:
01111 if (optimize_size)
01112 *total = COSTS_N_INSNS (2);
01113 else
01114 *total = COSTS_N_INSNS (25);
01115 return false;
01116
01117 case MOD:
01118 if (optimize_size)
01119 *total = COSTS_N_INSNS (2);
01120 else
01121 *total = COSTS_N_INSNS (26);
01122 return false;
01123
01124 case ABS:
01125
01126 *total = COSTS_N_INSNS (3);
01127 return false;
01128
01129 case ZERO_EXTEND:
01130
01131 *total = COSTS_N_INSNS (1);
01132 return false;
01133
01134 case SIGN_EXTEND:
01135 if (GET_MODE (x) == HImode)
01136 *total = COSTS_N_INSNS (1);
01137 else if (GET_MODE (x) == SImode)
01138 *total = COSTS_N_INSNS (6);
01139 else
01140 *total = COSTS_N_INSNS (2);
01141 return false;
01142
01143 case ASHIFT:
01144 case LSHIFTRT:
01145 case ASHIFTRT:
01146 if (optimize_size)
01147 *total = COSTS_N_INSNS (1);
01148 else if (GET_MODE (x) == QImode)
01149 {
01150 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
01151 *total = COSTS_N_INSNS (8);
01152 else
01153 *total = COSTS_N_INSNS (INTVAL (XEXP (x, 1)));
01154 }
01155 else if (GET_MODE (x) == HImode)
01156 {
01157 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
01158 {
01159 if (abs (INTVAL (XEXP (x, 1))) == 1)
01160 *total = COSTS_N_INSNS (1);
01161 else
01162 *total = COSTS_N_INSNS (2.5 + 0.5 * INTVAL (XEXP (x, 1)));
01163 }
01164 else
01165 *total = COSTS_N_INSNS (10);
01166 }
01167 else if (GET_MODE (x) == SImode)
01168 {
01169 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
01170 *total = COSTS_N_INSNS (2.5 + 0.5 * INTVAL (XEXP (x, 1)));
01171 else
01172 *total = COSTS_N_INSNS (18);
01173 }
01174 return false;
01175
01176 default:
01177 return false;
01178 }
01179 }
01180
01181 const char *
01182 output_jump(const char *pos, const char *neg, int length)
01183 {
01184 static int x = 0;
01185
01186 static char buf[1000];
01187
01188 #if 0
01189
01190
01191
01192
01193
01194 if (cc_status.flags & CC_IN_FPU)
01195 output_asm_insn("cfcc", NULL);
01196 #endif
01197
01198 switch (length)
01199 {
01200 case 1:
01201
01202 strcpy(buf, pos);
01203 strcat(buf, " %l0");
01204
01205 return buf;
01206
01207 case 3:
01208
01209 sprintf(buf, "%s JMP_%d\n\tjmp %%l0\nJMP_%d:", neg, x, x);
01210
01211 x++;
01212
01213 return buf;
01214
01215 default:
01216
01217 abort();
01218 }
01219
01220 }
01221
01222 void
01223 notice_update_cc_on_set(rtx exp, rtx insn ATTRIBUTE_UNUSED)
01224 {
01225 if (GET_CODE (SET_DEST (exp)) == CC0)
01226 {
01227 cc_status.flags = 0;
01228 cc_status.value1 = SET_DEST (exp);
01229 cc_status.value2 = SET_SRC (exp);
01230
01231
01232
01233
01234
01235 }
01236 else if ((GET_CODE (SET_DEST (exp)) == REG
01237 || GET_CODE (SET_DEST (exp)) == MEM)
01238 && GET_CODE (SET_SRC (exp)) != PC
01239 && (GET_MODE (SET_DEST(exp)) == HImode
01240 || GET_MODE (SET_DEST(exp)) == QImode)
01241 && (GET_CODE (SET_SRC(exp)) == PLUS
01242 || GET_CODE (SET_SRC(exp)) == MINUS
01243 || GET_CODE (SET_SRC(exp)) == AND
01244 || GET_CODE (SET_SRC(exp)) == IOR
01245 || GET_CODE (SET_SRC(exp)) == XOR
01246 || GET_CODE (SET_SRC(exp)) == NOT
01247 || GET_CODE (SET_SRC(exp)) == NEG
01248 || GET_CODE (SET_SRC(exp)) == REG
01249 || GET_CODE (SET_SRC(exp)) == MEM))
01250 {
01251 cc_status.flags = 0;
01252 cc_status.value1 = SET_SRC (exp);
01253 cc_status.value2 = SET_DEST (exp);
01254
01255 if (cc_status.value1 && GET_CODE (cc_status.value1) == REG
01256 && cc_status.value2
01257 && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2))
01258 cc_status.value2 = 0;
01259 if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM
01260 && cc_status.value2
01261 && GET_CODE (cc_status.value2) == MEM)
01262 cc_status.value2 = 0;
01263 }
01264 else if (GET_CODE (SET_SRC (exp)) == CALL)
01265 {
01266 CC_STATUS_INIT;
01267 }
01268 else if (GET_CODE (SET_DEST (exp)) == REG)
01269
01270 {
01271 if ((cc_status.value1
01272 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1)))
01273 cc_status.value1 = 0;
01274 if ((cc_status.value2
01275 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2)))
01276 cc_status.value2 = 0;
01277 }
01278 else if (SET_DEST(exp) == pc_rtx)
01279 {
01280
01281 }
01282 else
01283 {
01284
01285
01286
01287 CC_STATUS_INIT;
01288 }
01289 }
01290
01291
01292 int
01293 simple_memory_operand(rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
01294 {
01295 rtx addr;
01296
01297
01298 if (GET_CODE (op) != MEM)
01299 return FALSE;
01300
01301 #if 0
01302
01303 if (GET_MODE_SIZE (GET_MODE (op)) > (HAVE_64BIT_P () ? 8 : 4))
01304 return FALSE;
01305 #endif
01306
01307
01308
01309 indirection:
01310
01311 addr = XEXP (op, 0);
01312
01313 switch (GET_CODE (addr))
01314 {
01315 case REG:
01316
01317 return 1;
01318
01319 case PRE_DEC:
01320 case POST_INC:
01321
01322 return 0;
01323
01324 case MEM:
01325
01326
01327
01328
01329 if (GET_CODE (XEXP (addr, 0)) == REG)
01330 return 0;
01331
01332 op=addr;
01333 goto indirection;
01334
01335 case CONST_INT:
01336 case LABEL_REF:
01337 case CONST:
01338 case SYMBOL_REF:
01339
01340 return 0;
01341
01342 case PLUS:
01343
01344 return 0;
01345
01346 default:
01347 break;
01348 }
01349
01350 return FALSE;
01351 }
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365 const char *
01366 output_block_move(rtx *operands)
01367 {
01368 static int count = 0;
01369 char buf[200];
01370
01371 if (GET_CODE(operands[2]) == CONST_INT
01372 && ! optimize_size)
01373 {
01374 if (INTVAL(operands[2]) < 16
01375 && INTVAL(operands[3]) == 1)
01376 {
01377 register int i;
01378
01379 for (i = 1; i <= INTVAL(operands[2]); i++)
01380 output_asm_insn("movb (%1)+, (%0)+", operands);
01381
01382 return "";
01383 }
01384 else if (INTVAL(operands[2]) < 32)
01385 {
01386 register int i;
01387
01388 for (i = 1; i <= INTVAL(operands[2])/2; i++)
01389 output_asm_insn("mov (%1)+, (%0)+", operands);
01390
01391
01392
01393
01394
01395
01396
01397 return "";
01398 }
01399
01400
01401
01402 }
01403
01404 if (CONSTANT_P(operands[2]) )
01405 {
01406
01407 output_asm_insn("mov %2, %4", operands);
01408 }
01409 else
01410 {
01411
01412 operands[4] = operands[2];
01413 }
01414
01415
01416
01417 switch (INTVAL(operands[3]))
01418 {
01419 case 1:
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433 sprintf(buf, "\nmovestrhi%d:", count);
01434 output_asm_insn(buf, NULL);
01435
01436 output_asm_insn("movb (%1)+, (%0)+", operands);
01437
01438 if (TARGET_45)
01439 {
01440 sprintf(buf, "sob %%4, movestrhi%d", count);
01441 output_asm_insn(buf, operands);
01442 }
01443 else
01444 {
01445 output_asm_insn("dec %4", operands);
01446
01447 sprintf(buf, "bgt movestrhi%d", count);
01448 output_asm_insn(buf, NULL);
01449 }
01450
01451 count ++;
01452 break;
01453
01454 case 2:
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470 generate_compact_code:
01471
01472 output_asm_insn("asr %4", operands);
01473
01474 sprintf(buf, "\nmovestrhi%d:", count);
01475 output_asm_insn(buf, NULL);
01476
01477 output_asm_insn("mov (%1)+, (%0)+", operands);
01478
01479 if (TARGET_45)
01480 {
01481 sprintf(buf, "sob %%4, movestrhi%d", count);
01482 output_asm_insn(buf, operands);
01483 }
01484 else
01485 {
01486 output_asm_insn("dec %4", operands);
01487
01488 sprintf(buf, "bgt movestrhi%d", count);
01489 output_asm_insn(buf, NULL);
01490 }
01491
01492 count ++;
01493 break;
01494
01495 case 4:
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514 if (optimize_size)
01515 goto generate_compact_code;
01516
01517 output_asm_insn("asr %4", operands);
01518 output_asm_insn("asr %4", operands);
01519
01520 sprintf(buf, "\nmovestrhi%d:", count);
01521 output_asm_insn(buf, NULL);
01522
01523 output_asm_insn("mov (%1)+, (%0)+", operands);
01524 output_asm_insn("mov (%1)+, (%0)+", operands);
01525
01526 if (TARGET_45)
01527 {
01528 sprintf(buf, "sob %%4, movestrhi%d", count);
01529 output_asm_insn(buf, operands);
01530 }
01531 else
01532 {
01533 output_asm_insn("dec %4", operands);
01534
01535 sprintf(buf, "bgt movestrhi%d", count);
01536 output_asm_insn(buf, NULL);
01537 }
01538
01539 count ++;
01540 break;
01541
01542 default:
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565 if (optimize_size)
01566 goto generate_compact_code;
01567
01568 output_asm_insn("asr %4", operands);
01569 output_asm_insn("asr %4", operands);
01570 output_asm_insn("asr %4", operands);
01571
01572 sprintf(buf, "\nmovestrhi%d:", count);
01573 output_asm_insn(buf, NULL);
01574
01575 output_asm_insn("mov (%1)+, (%0)+", operands);
01576 output_asm_insn("mov (%1)+, (%0)+", operands);
01577 output_asm_insn("mov (%1)+, (%0)+", operands);
01578 output_asm_insn("mov (%1)+, (%0)+", operands);
01579
01580 if (TARGET_45)
01581 {
01582 sprintf(buf, "sob %%4, movestrhi%d", count);
01583 output_asm_insn(buf, operands);
01584 }
01585 else
01586 {
01587 output_asm_insn("dec %4", operands);
01588
01589 sprintf(buf, "bgt movestrhi%d", count);
01590 output_asm_insn(buf, NULL);
01591 }
01592
01593 count ++;
01594 break;
01595
01596 ;
01597
01598 }
01599
01600 return "";
01601 }
01602
01603 int
01604 legitimate_address_p (enum machine_mode mode, rtx address)
01605 {
01606
01607 GO_IF_LEGITIMATE_ADDRESS(mode, address, win);
01608
01609 return 0;
01610
01611 win:
01612 return 1;
01613
01614
01615 }
01616
01617
01618
01619
01620 int
01621 legitimate_const_double_p (rtx address)
01622 {
01623 REAL_VALUE_TYPE r;
01624 long sval[2];
01625 REAL_VALUE_FROM_CONST_DOUBLE (r, address);
01626 REAL_VALUE_TO_TARGET_DOUBLE (r, sval);
01627 if ((sval[0] & 0xffff) == 0 && sval[1] == 0)
01628 return 1;
01629 return 0;
01630 }
01631
01632
01633
01634
01635
01636
01637 void
01638 output_addr_const_pdp11 (FILE *file, rtx x)
01639 {
01640 char buf[256];
01641
01642 restart:
01643 switch (GET_CODE (x))
01644 {
01645 case PC:
01646 if (flag_pic)
01647 putc ('.', file);
01648 else
01649 abort ();
01650 break;
01651
01652 case SYMBOL_REF:
01653 assemble_name (file, XSTR (x, 0));
01654 break;
01655
01656 case LABEL_REF:
01657 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
01658 assemble_name (file, buf);
01659 break;
01660
01661 case CODE_LABEL:
01662 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
01663 assemble_name (file, buf);
01664 break;
01665
01666 case CONST_INT:
01667
01668
01669 fprintf (file, "%#ho", (unsigned short) INTVAL (x));
01670 break;
01671
01672 case CONST:
01673
01674
01675 output_addr_const_pdp11 (file, XEXP (x, 0));
01676 break;
01677
01678 case CONST_DOUBLE:
01679 if (GET_MODE (x) == VOIDmode)
01680 {
01681
01682 if (CONST_DOUBLE_HIGH (x))
01683 abort ();
01684 else
01685 fprintf (file, "%#ho", (unsigned short) CONST_DOUBLE_LOW (x));
01686 }
01687 else
01688
01689
01690 output_operand_lossage ("floating constant misused");
01691 break;
01692
01693 case PLUS:
01694
01695 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
01696 {
01697 output_addr_const_pdp11 (file, XEXP (x, 1));
01698 if (INTVAL (XEXP (x, 0)) >= 0)
01699 fprintf (file, "+");
01700 output_addr_const_pdp11 (file, XEXP (x, 0));
01701 }
01702 else
01703 {
01704 output_addr_const_pdp11 (file, XEXP (x, 0));
01705 if (INTVAL (XEXP (x, 1)) >= 0)
01706 fprintf (file, "+");
01707 output_addr_const_pdp11 (file, XEXP (x, 1));
01708 }
01709 break;
01710
01711 case MINUS:
01712
01713
01714 x = simplify_subtraction (x);
01715 if (GET_CODE (x) != MINUS)
01716 goto restart;
01717
01718 output_addr_const_pdp11 (file, XEXP (x, 0));
01719 fprintf (file, "-");
01720 if (GET_CODE (XEXP (x, 1)) == CONST_INT
01721 && INTVAL (XEXP (x, 1)) < 0)
01722 {
01723 fprintf (file, targetm.asm_out.open_paren);
01724 output_addr_const_pdp11 (file, XEXP (x, 1));
01725 fprintf (file, targetm.asm_out.close_paren);
01726 }
01727 else
01728 output_addr_const_pdp11 (file, XEXP (x, 1));
01729 break;
01730
01731 case ZERO_EXTEND:
01732 case SIGN_EXTEND:
01733 output_addr_const_pdp11 (file, XEXP (x, 0));
01734 break;
01735
01736 default:
01737 output_operand_lossage ("invalid expression as operand");
01738 }
01739 }
01740
01741
01742
01743 static bool
01744 pdp11_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
01745 {
01746
01747
01748
01749
01750
01751
01752 return (TYPE_MODE (type) == DImode
01753 || (TYPE_MODE (type) == DFmode && ! TARGET_AC0));
01754 }