00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef _S390_H
00025 #define _S390_H
00026
00027
00028
00029 #if defined (IN_LIBGCC2) && !defined (__s390x__)
00030 #include <config/s390/fixdfdi.h>
00031 #endif
00032
00033
00034
00035
00036
00037 enum processor_type
00038 {
00039 PROCESSOR_9672_G5,
00040 PROCESSOR_9672_G6,
00041 PROCESSOR_2064_Z900,
00042 PROCESSOR_2084_Z990,
00043 PROCESSOR_max
00044 };
00045
00046
00047
00048 enum processor_flags
00049 {
00050 PF_IEEE_FLOAT = 1,
00051 PF_ZARCH = 2,
00052 PF_LONG_DISPLACEMENT = 4
00053 };
00054
00055 extern enum processor_type s390_tune;
00056 extern enum processor_flags s390_tune_flags;
00057 extern const char *s390_tune_string;
00058
00059 extern enum processor_type s390_arch;
00060 extern enum processor_flags s390_arch_flags;
00061 extern const char *s390_arch_string;
00062
00063 extern const char *s390_warn_framesize_string;
00064 extern const char *s390_warn_dynamicstack_string;
00065 extern const char *s390_stack_size_string;
00066 extern const char *s390_stack_guard_string;
00067
00068 #define TARGET_CPU_IEEE_FLOAT \
00069 (s390_arch_flags & PF_IEEE_FLOAT)
00070 #define TARGET_CPU_ZARCH \
00071 (s390_arch_flags & PF_ZARCH)
00072 #define TARGET_CPU_LONG_DISPLACEMENT \
00073 (s390_arch_flags & PF_LONG_DISPLACEMENT)
00074
00075 #define TARGET_LONG_DISPLACEMENT \
00076 (TARGET_ZARCH && TARGET_CPU_LONG_DISPLACEMENT)
00077
00078
00079
00080
00081
00082 #define TARGET_TPF 0
00083
00084
00085 #define TARGET_CPU_CPP_BUILTINS() \
00086 do \
00087 { \
00088 builtin_assert ("cpu=s390"); \
00089 builtin_assert ("machine=s390"); \
00090 builtin_define ("__s390__"); \
00091 if (TARGET_64BIT) \
00092 builtin_define ("__s390x__"); \
00093 } \
00094 while (0)
00095
00096
00097 extern int target_flags;
00098
00099 #define MASK_HARD_FLOAT 0x01
00100 #define MASK_SMALL_EXEC 0x04
00101 #define MASK_DEBUG_ARG 0x08
00102 #define MASK_64BIT 0x10
00103 #define MASK_ZARCH 0x20
00104 #define MASK_MVCLE 0x40
00105 #define MASK_TPF_PROFILING 0x80
00106 #define MASK_NO_FUSED_MADD 0x100
00107 #define MASK_BACKCHAIN 0x200
00108 #define MASK_PACKED_STACK 0x400
00109
00110 #define TARGET_HARD_FLOAT (target_flags & MASK_HARD_FLOAT)
00111 #define TARGET_SOFT_FLOAT (!(target_flags & MASK_HARD_FLOAT))
00112 #define TARGET_SMALL_EXEC (target_flags & MASK_SMALL_EXEC)
00113 #define TARGET_DEBUG_ARG (target_flags & MASK_DEBUG_ARG)
00114 #define TARGET_64BIT (target_flags & MASK_64BIT)
00115 #define TARGET_ZARCH (target_flags & MASK_ZARCH)
00116 #define TARGET_MVCLE (target_flags & MASK_MVCLE)
00117 #define TARGET_TPF_PROFILING (target_flags & MASK_TPF_PROFILING)
00118 #define TARGET_NO_FUSED_MADD (target_flags & MASK_NO_FUSED_MADD)
00119 #define TARGET_FUSED_MADD (! TARGET_NO_FUSED_MADD)
00120 #define TARGET_BACKCHAIN (target_flags & MASK_BACKCHAIN)
00121 #define TARGET_PACKED_STACK (target_flags & MASK_PACKED_STACK)
00122
00123
00124 #define TARGET_IBM_FLOAT 0
00125 #define TARGET_IEEE_FLOAT 1
00126
00127 #ifdef DEFAULT_TARGET_64BIT
00128 #define TARGET_DEFAULT (MASK_64BIT | MASK_ZARCH | MASK_HARD_FLOAT)
00129 #else
00130 #define TARGET_DEFAULT MASK_HARD_FLOAT
00131 #endif
00132
00133 #define TARGET_SWITCHES \
00134 { { "hard-float", 1, N_("Use hardware fp")}, \
00135 { "soft-float", -1, N_("Don't use hardware fp")}, \
00136 { "small-exec", 4, N_("Use bras for executable < 64k")}, \
00137 { "no-small-exec", -4, N_("Don't use bras")}, \
00138 { "debug", 8, N_("Additional debug prints")}, \
00139 { "no-debug", -8, N_("Don't print additional debug prints")}, \
00140 { "64", 16, N_("64 bit ABI")}, \
00141 { "31", -16, N_("31 bit ABI")}, \
00142 { "zarch", 32, N_("z/Architecture")}, \
00143 { "esa", -32, N_("ESA/390 architecture")}, \
00144 { "mvcle", 64, N_("mvcle use")}, \
00145 { "no-mvcle", -64, N_("mvc&ex")}, \
00146 { "tpf-trace", 128, N_("Enable tpf OS tracing code")}, \
00147 { "no-tpf-trace", -128, N_("Disable tpf OS tracing code")}, \
00148 { "no-fused-madd", 256, N_("Disable fused multiply/add instructions")},\
00149 { "fused-madd", -256, N_("Enable fused multiply/add instructions")}, \
00150 { "backchain", 512, N_("Maintain backchain pointer")}, \
00151 { "no-backchain", -512, N_("Don't maintain backchain pointer")}, \
00152 { "packed-stack", 1024, N_("Use packed stack layout")}, \
00153 { "no-packed-stack", -1024, N_("Don't use packed stack layout")}, \
00154 { "", TARGET_DEFAULT, 0 } }
00155
00156 #define TARGET_OPTIONS \
00157 { { "tune=", &s390_tune_string, \
00158 N_("Schedule code for given CPU"), 0}, \
00159 { "arch=", &s390_arch_string, \
00160 N_("Generate code for given CPU"), 0}, \
00161 { "warn-framesize=", &s390_warn_framesize_string, \
00162 N_("Warn if a single function's framesize exceeds the given framesize"), \
00163 0}, \
00164 { "warn-dynamicstack", &s390_warn_dynamicstack_string, \
00165 N_("Warn if a function uses alloca or creates an array with dynamic size"),\
00166 0}, \
00167 { "stack-size=", &s390_stack_size_string, \
00168 N_("Emit extra code in the function prologue in order to trap if the stack"\
00169 "size exceeds the given limit"), 0}, \
00170 { "stack-guard=", &s390_stack_guard_string, \
00171 N_("Set the max. number of bytes which has to be left to stack size " \
00172 "before a trap instruction is triggered"), 0}, \
00173 }
00174
00175
00176 #define OPTION_DEFAULT_SPECS \
00177 { "mode", "%{!mesa:%{!mzarch:-m%(VALUE)}}" }, \
00178 { "arch", "%{!march=*:-march=%(VALUE)}" }, \
00179 { "tune", "%{!mtune=*:-mtune=%(VALUE)}" }
00180
00181
00182 #ifdef DEFAULT_TARGET_64BIT
00183 #define DRIVER_SELF_SPECS \
00184 "%{!m31:%{!m64:-m64}}", \
00185 "%{!mesa:%{!mzarch:%{m31:-mesa}%{m64:-mzarch}}}", \
00186 "%{!march=*:%{mesa:-march=g5}%{mzarch:-march=z900}}"
00187 #else
00188 #define DRIVER_SELF_SPECS \
00189 "%{!m31:%{!m64:-m31}}", \
00190 "%{!mesa:%{!mzarch:%{m31:-mesa}%{m64:-mzarch}}}", \
00191 "%{!march=*:%{mesa:-march=g5}%{mzarch:-march=z900}}"
00192 #endif
00193
00194
00195 #ifdef DEFAULT_TARGET_64BIT
00196 #define TARGET_VERSION fprintf (stderr, " (zSeries)");
00197 #else
00198 #define TARGET_VERSION fprintf (stderr, " (S/390)");
00199 #endif
00200
00201
00202 #define OPTIMIZATION_OPTIONS(LEVEL, SIZE) optimization_options(LEVEL, SIZE)
00203 #define OVERRIDE_OPTIONS override_options ()
00204
00205
00206 #define CAN_DEBUG_WITHOUT_FP
00207
00208
00209
00210 #ifdef IN_LIBGCC2
00211 #undef TARGET_64BIT
00212 #ifdef __s390x__
00213 #define TARGET_64BIT 1
00214 #else
00215 #define TARGET_64BIT 0
00216 #endif
00217 #endif
00218
00219
00220
00221
00222
00223 #define BITS_BIG_ENDIAN 1
00224 #define BYTES_BIG_ENDIAN 1
00225 #define WORDS_BIG_ENDIAN 1
00226
00227
00228 #define UNITS_PER_WORD (TARGET_64BIT ? 8 : 4)
00229 #ifndef IN_LIBGCC2
00230 #define MIN_UNITS_PER_WORD 4
00231 #endif
00232 #define MAX_BITS_PER_WORD 64
00233
00234
00235 #define PROMOTE_FUNCTION_MODE(MODE, UNSIGNEDP, TYPE) \
00236 if (INTEGRAL_MODE_P (MODE) && \
00237 GET_MODE_SIZE (MODE) < UNITS_PER_WORD) { \
00238 (MODE) = Pmode; \
00239 }
00240
00241
00242 #define PARM_BOUNDARY (TARGET_64BIT ? 64 : 32)
00243
00244
00245 #define STACK_BOUNDARY 64
00246
00247
00248 #define FUNCTION_BOUNDARY 32
00249
00250
00251 #define BIGGEST_ALIGNMENT 64
00252
00253
00254 #define EMPTY_FIELD_BOUNDARY 32
00255
00256
00257 #define CONSTANT_ALIGNMENT(EXP, ALIGN) (ALIGN) < 16 ? 16 : (ALIGN)
00258 #define DATA_ALIGNMENT(TYPE, ALIGN) (ALIGN) < 16 ? 16 : (ALIGN)
00259
00260
00261 #define STRICT_ALIGNMENT 0
00262
00263
00264
00265
00266
00267 #define STACK_SAVEAREA_MODE(LEVEL) \
00268 (LEVEL == SAVE_FUNCTION ? VOIDmode \
00269 : LEVEL == SAVE_NONLOCAL ? (TARGET_64BIT ? OImode : TImode) : Pmode)
00270
00271
00272 #define TARGET_FLOAT_FORMAT \
00273 (TARGET_IEEE_FLOAT? IEEE_FLOAT_FORMAT : IBM_FLOAT_FORMAT)
00274
00275
00276
00277
00278
00279 #define SHORT_TYPE_SIZE 16
00280 #define INT_TYPE_SIZE 32
00281 #define LONG_TYPE_SIZE (TARGET_64BIT ? 64 : 32)
00282 #define LONG_LONG_TYPE_SIZE 64
00283 #define FLOAT_TYPE_SIZE 32
00284 #define DOUBLE_TYPE_SIZE 64
00285 #define LONG_DOUBLE_TYPE_SIZE 64
00286
00287
00288 #define DEFAULT_SIGNED_CHAR 0
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315 #define FIRST_PSEUDO_REGISTER 38
00316
00317
00318 #define GENERAL_REGNO_P(N) ((int)(N) >= 0 && (N) < 16)
00319 #define ADDR_REGNO_P(N) ((N) >= 1 && (N) < 16)
00320 #define FP_REGNO_P(N) ((N) >= 16 && (N) < (TARGET_IEEE_FLOAT? 32 : 20))
00321 #define CC_REGNO_P(N) ((N) == 33)
00322 #define FRAME_REGNO_P(N) ((N) == 32 || (N) == 34 || (N) == 35)
00323 #define ACCESS_REGNO_P(N) ((N) == 36 || (N) == 37)
00324
00325 #define GENERAL_REG_P(X) (REG_P (X) && GENERAL_REGNO_P (REGNO (X)))
00326 #define ADDR_REG_P(X) (REG_P (X) && ADDR_REGNO_P (REGNO (X)))
00327 #define FP_REG_P(X) (REG_P (X) && FP_REGNO_P (REGNO (X)))
00328 #define CC_REG_P(X) (REG_P (X) && CC_REGNO_P (REGNO (X)))
00329 #define FRAME_REG_P(X) (REG_P (X) && FRAME_REGNO_P (REGNO (X)))
00330 #define ACCESS_REG_P(X) (REG_P (X) && ACCESS_REGNO_P (REGNO (X)))
00331
00332 #define SIBCALL_REGNUM 1
00333 #define BASE_REGNUM 13
00334 #define RETURN_REGNUM 14
00335 #define CC_REGNUM 33
00336 #define TP_REGNUM 36
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353 #define FIXED_REGISTERS \
00354 { 0, 0, 0, 0, \
00355 0, 0, 0, 0, \
00356 0, 0, 0, 0, \
00357 0, 1, 1, 1, \
00358 0, 0, 0, 0, \
00359 0, 0, 0, 0, \
00360 0, 0, 0, 0, \
00361 0, 0, 0, 0, \
00362 1, 1, 1, 1, \
00363 1, 1 }
00364
00365 #define CALL_USED_REGISTERS \
00366 { 1, 1, 1, 1, \
00367 1, 1, 0, 0, \
00368 0, 0, 0, 0, \
00369 0, 1, 1, 1, \
00370 1, 1, 1, 1, \
00371 1, 1, 1, 1, \
00372 1, 1, 1, 1, \
00373 1, 1, 1, 1, \
00374 1, 1, 1, 1, \
00375 1, 1 }
00376
00377 #define CALL_REALLY_USED_REGISTERS \
00378 { 1, 1, 1, 1, \
00379 1, 1, 0, 0, \
00380 0, 0, 0, 0, \
00381 0, 0, 0, 0, \
00382 1, 1, 1, 1, \
00383 1, 1, 1, 1, \
00384 1, 1, 1, 1, \
00385 1, 1, 1, 1, \
00386 1, 1, 1, 1, \
00387 0, 0 }
00388
00389 #define CONDITIONAL_REGISTER_USAGE s390_conditional_register_usage ()
00390
00391
00392 #define REG_ALLOC_ORDER \
00393 { 1, 2, 3, 4, 5, 0, 13, 12, 11, 10, 9, 8, 7, 6, 14, \
00394 16, 17, 18, 19, 20, 21, 22, 23, \
00395 24, 25, 26, 27, 28, 29, 30, 31, \
00396 15, 32, 33, 34, 35, 36, 37 }
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415 #define HARD_REGNO_NREGS(REGNO, MODE) \
00416 (FP_REGNO_P(REGNO)? \
00417 (GET_MODE_CLASS(MODE) == MODE_COMPLEX_FLOAT ? 2 : 1) : \
00418 GENERAL_REGNO_P(REGNO)? \
00419 ((GET_MODE_SIZE(MODE)+UNITS_PER_WORD-1) / UNITS_PER_WORD) : \
00420 ACCESS_REGNO_P(REGNO)? \
00421 ((GET_MODE_SIZE(MODE)+4-1) / 4) : \
00422 1)
00423
00424 #define HARD_REGNO_MODE_OK(REGNO, MODE) \
00425 (FP_REGNO_P(REGNO)? \
00426 ((MODE) == SImode || (MODE) == DImode || \
00427 GET_MODE_CLASS(MODE) == MODE_FLOAT || \
00428 GET_MODE_CLASS(MODE) == MODE_COMPLEX_FLOAT) : \
00429 GENERAL_REGNO_P(REGNO)? \
00430 (HARD_REGNO_NREGS(REGNO, MODE) == 1 || !((REGNO) & 1)) : \
00431 CC_REGNO_P(REGNO)? \
00432 GET_MODE_CLASS (MODE) == MODE_CC : \
00433 FRAME_REGNO_P(REGNO)? \
00434 (enum machine_mode) (MODE) == Pmode : \
00435 ACCESS_REGNO_P(REGNO)? \
00436 (((MODE) == SImode || ((enum machine_mode) (MODE) == Pmode)) \
00437 && (HARD_REGNO_NREGS(REGNO, MODE) == 1 || !((REGNO) & 1))) : \
00438 0)
00439
00440 #define MODES_TIEABLE_P(MODE1, MODE2) \
00441 (((MODE1) == SFmode || (MODE1) == DFmode) \
00442 == ((MODE2) == SFmode || (MODE2) == DFmode))
00443
00444
00445
00446 #define CLASS_MAX_NREGS(CLASS, MODE) \
00447 ((CLASS) == FP_REGS ? \
00448 (GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT ? 2 : 1) : \
00449 (CLASS) == ACCESS_REGS ? \
00450 (GET_MODE_SIZE (MODE) + 4 - 1) / 4 : \
00451 (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
00452
00453
00454
00455
00456
00457
00458 #define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
00459 (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
00460 ? reg_classes_intersect_p (FP_REGS, CLASS) \
00461 || reg_classes_intersect_p (ACCESS_REGS, CLASS) : 0)
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484 enum reg_class
00485 {
00486 NO_REGS, CC_REGS, ADDR_REGS, GENERAL_REGS, ACCESS_REGS,
00487 ADDR_CC_REGS, GENERAL_CC_REGS,
00488 FP_REGS, ADDR_FP_REGS, GENERAL_FP_REGS,
00489 ALL_REGS, LIM_REG_CLASSES
00490 };
00491 #define N_REG_CLASSES (int) LIM_REG_CLASSES
00492
00493 #define REG_CLASS_NAMES \
00494 { "NO_REGS", "CC_REGS", "ADDR_REGS", "GENERAL_REGS", "ACCESS_REGS", \
00495 "ADDR_CC_REGS", "GENERAL_CC_REGS", \
00496 "FP_REGS", "ADDR_FP_REGS", "GENERAL_FP_REGS", "ALL_REGS" }
00497
00498
00499 #define REG_CLASS_CONTENTS \
00500 { \
00501 { 0x00000000, 0x00000000 }, \
00502 { 0x00000000, 0x00000002 }, \
00503 { 0x0000fffe, 0x0000000d }, \
00504 { 0x0000ffff, 0x0000000d }, \
00505 { 0x00000000, 0x00000030 }, \
00506 { 0x0000fffe, 0x0000000f }, \
00507 { 0x0000ffff, 0x0000000f }, \
00508 { 0xffff0000, 0x00000000 }, \
00509 { 0xfffffffe, 0x0000000d }, \
00510 { 0xffffffff, 0x0000000d }, \
00511 { 0xffffffff, 0x0000003f }, \
00512 }
00513
00514
00515 extern const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER];
00516 #define REGNO_REG_CLASS(REGNO) (regclass_map[REGNO])
00517
00518
00519 #define INDEX_REG_CLASS ADDR_REGS
00520 #define BASE_REG_CLASS ADDR_REGS
00521
00522
00523
00524 #define REGNO_OK_FOR_INDEX_P(REGNO) \
00525 (((REGNO) < FIRST_PSEUDO_REGISTER \
00526 && REGNO_REG_CLASS ((REGNO)) == ADDR_REGS) \
00527 || (reg_renumber[REGNO] > 0 && reg_renumber[REGNO] < 16))
00528 #define REGNO_OK_FOR_BASE_P(REGNO) REGNO_OK_FOR_INDEX_P (REGNO)
00529
00530
00531
00532
00533 #define PREFERRED_RELOAD_CLASS(X, CLASS) \
00534 s390_preferred_reload_class ((X), (CLASS))
00535
00536
00537
00538 #define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, IN) \
00539 s390_secondary_input_reload_class ((CLASS), (MODE), (IN))
00540
00541
00542
00543 #define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, OUT) \
00544 s390_secondary_output_reload_class ((CLASS), (MODE), (OUT))
00545
00546
00547 #define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \
00548 ((CLASS1) != (CLASS2) && ((CLASS1) == FP_REGS || (CLASS2) == FP_REGS))
00549
00550
00551
00552 #define SECONDARY_MEMORY_NEEDED_MODE(MODE) \
00553 (GET_MODE_BITSIZE (MODE) < 32 \
00554 ? mode_for_size (32, GET_MODE_CLASS (MODE), 0) \
00555 : MODE)
00556
00557
00558
00559
00560 #define REG_CLASS_FROM_LETTER(C) \
00561 ((C) == 'a' ? ADDR_REGS : \
00562 (C) == 'd' ? GENERAL_REGS : \
00563 (C) == 'f' ? FP_REGS : \
00564 (C) == 'c' ? CC_REGS : \
00565 (C) == 't' ? ACCESS_REGS : NO_REGS)
00566
00567 #define CONST_OK_FOR_CONSTRAINT_P(VALUE, C, STR) \
00568 s390_const_ok_for_constraint_p ((VALUE), (C), (STR))
00569
00570 #define CONST_DOUBLE_OK_FOR_CONSTRAINT_P(VALUE, C, STR) 1
00571
00572 #define EXTRA_CONSTRAINT_STR(OP, C, STR) \
00573 s390_extra_constraint_str ((OP), (C), (STR))
00574 #define EXTRA_MEMORY_CONSTRAINT(C, STR) \
00575 ((C) == 'Q' || (C) == 'R' || (C) == 'S' || (C) == 'T' || (C) == 'A')
00576 #define EXTRA_ADDRESS_CONSTRAINT(C, STR) \
00577 ((C) == 'U' || (C) == 'W' || (C) == 'Y')
00578
00579 #define CONSTRAINT_LEN(C, STR) \
00580 ((C) == 'N' ? 5 : \
00581 (C) == 'A' ? 2 : \
00582 (C) == 'B' ? 2 : DEFAULT_CONSTRAINT_LEN ((C), (STR)))
00583
00584
00585
00586
00587
00588
00589 #define STACK_GROWS_DOWNWARD
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599 #define STACK_POINTER_OFFSET (TARGET_64BIT ? 160 : 96)
00600
00601
00602 extern int current_function_outgoing_args_size;
00603 #define STARTING_FRAME_OFFSET \
00604 (STACK_POINTER_OFFSET + current_function_outgoing_args_size)
00605
00606
00607
00608 #define STACK_DYNAMIC_OFFSET(FUNDECL) (STARTING_FRAME_OFFSET)
00609
00610
00611
00612
00613 #define FIRST_PARM_OFFSET(FNDECL) 0
00614
00615
00616
00617 #define INITIAL_FRAME_ADDRESS_RTX \
00618 (TARGET_PACKED_STACK ? \
00619 plus_constant (arg_pointer_rtx, -UNITS_PER_WORD) : \
00620 plus_constant (arg_pointer_rtx, -STACK_POINTER_OFFSET))
00621
00622
00623
00624
00625
00626 #define DYNAMIC_CHAIN_ADDRESS(FRAME) \
00627 (TARGET_PACKED_STACK ? \
00628 plus_constant ((FRAME), STACK_POINTER_OFFSET - UNITS_PER_WORD) : (FRAME))
00629
00630 #define RETURN_ADDR_RTX(COUNT, FRAME) \
00631 s390_return_addr_rtx ((COUNT), DYNAMIC_CHAIN_ADDRESS ((FRAME)))
00632
00633
00634 #define MASK_RETURN_ADDR (TARGET_64BIT ? constm1_rtx : GEN_INT (0x7fffffff))
00635
00636
00637
00638
00639
00640 #define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, RETURN_REGNUM)
00641 #define INCOMING_FRAME_SP_OFFSET STACK_POINTER_OFFSET
00642 #define DWARF_FRAME_RETURN_COLUMN 14
00643
00644
00645 #define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + 6 : INVALID_REGNUM)
00646 #define EH_RETURN_HANDLER_RTX gen_rtx_MEM (Pmode, return_address_pointer_rtx)
00647
00648
00649 #define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
00650 (flag_pic \
00651 ? ((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_sdata4 \
00652 : DW_EH_PE_absptr)
00653
00654
00655
00656
00657 #define STACK_POINTER_REGNUM 15
00658 #define FRAME_POINTER_REGNUM 34
00659 #define HARD_FRAME_POINTER_REGNUM 11
00660 #define ARG_POINTER_REGNUM 32
00661 #define RETURN_ADDRESS_POINTER_REGNUM 35
00662
00663
00664
00665
00666 #define STATIC_CHAIN_REGNUM 0
00667
00668
00669
00670
00671 #define DWARF_FRAME_REGISTERS 34
00672
00673
00674
00675
00676 #define FRAME_POINTER_REQUIRED 0
00677
00678 #define INITIAL_FRAME_POINTER_OFFSET(DEPTH) (DEPTH) = 0
00679
00680 #define ELIMINABLE_REGS \
00681 {{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
00682 { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
00683 { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
00684 { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
00685 { RETURN_ADDRESS_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
00686 { RETURN_ADDRESS_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
00687
00688 #define CAN_ELIMINATE(FROM, TO) \
00689 s390_can_eliminate ((FROM), (TO))
00690
00691 #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
00692 (OFFSET) = s390_initial_elimination_offset ((FROM), (TO))
00693
00694
00695
00696
00697
00698 #define ACCUMULATE_OUTGOING_ARGS 1
00699
00700
00701 #define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, SIZE) 0
00702
00703
00704
00705
00706 typedef struct s390_arg_structure
00707 {
00708 int gprs;
00709 int fprs;
00710 }
00711 CUMULATIVE_ARGS;
00712
00713 #define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, NN, N_NAMED_ARGS) \
00714 ((CUM).gprs=0, (CUM).fprs=0)
00715
00716 #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
00717 s390_function_arg_advance (&CUM, MODE, TYPE, NAMED)
00718
00719 #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
00720 s390_function_arg (&CUM, MODE, TYPE, NAMED)
00721
00722
00723
00724 #define FUNCTION_ARG_REGNO_P(N) (((N) >=2 && (N) <7) || \
00725 (N) == 16 || (N) == 17)
00726
00727
00728
00729
00730 #define FUNCTION_VALUE(VALTYPE, FUNC) \
00731 s390_function_value ((VALTYPE), VOIDmode)
00732
00733 #define LIBCALL_VALUE(MODE) \
00734 s390_function_value (NULL, (MODE))
00735
00736
00737 #define FUNCTION_VALUE_REGNO_P(N) ((N) == 2 || (N) == 16)
00738
00739
00740
00741
00742
00743 #define EXIT_IGNORE_STACK 1
00744
00745
00746
00747
00748 #define FUNCTION_PROFILER(FILE, LABELNO) \
00749 s390_function_profiler ((FILE), ((LABELNO)))
00750
00751 #define PROFILE_BEFORE_PROLOGUE 1
00752
00753
00754
00755
00756 #define EXPAND_BUILTIN_VA_START(valist, nextarg) \
00757 s390_va_start (valist, nextarg)
00758
00759
00760
00761 #define TRAMPOLINE_SIZE (TARGET_64BIT ? 32 : 16)
00762
00763 #define INITIALIZE_TRAMPOLINE(ADDR, FNADDR, CXT) \
00764 s390_initialize_trampoline ((ADDR), (FNADDR), (CXT))
00765
00766 #define TRAMPOLINE_TEMPLATE(FILE) \
00767 s390_trampoline_template (FILE)
00768
00769
00770
00771
00772
00773 #define CONSTANT_ADDRESS_P(X) 0
00774
00775
00776 #define MAX_REGS_PER_ADDRESS 2
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789 #define REG_OK_FOR_INDEX_NONSTRICT_P(X) \
00790 ((GET_MODE (X) == Pmode) && \
00791 ((REGNO (X) >= FIRST_PSEUDO_REGISTER) \
00792 || REGNO_REG_CLASS (REGNO (X)) == ADDR_REGS))
00793
00794 #define REG_OK_FOR_BASE_NONSTRICT_P(X) REG_OK_FOR_INDEX_NONSTRICT_P (X)
00795
00796 #define REG_OK_FOR_INDEX_STRICT_P(X) \
00797 ((GET_MODE (X) == Pmode) && (REGNO_OK_FOR_INDEX_P (REGNO (X))))
00798
00799 #define REG_OK_FOR_BASE_STRICT_P(X) \
00800 ((GET_MODE (X) == Pmode) && (REGNO_OK_FOR_BASE_P (REGNO (X))))
00801
00802 #ifndef REG_OK_STRICT
00803 #define REG_OK_FOR_INDEX_P(X) REG_OK_FOR_INDEX_NONSTRICT_P(X)
00804 #define REG_OK_FOR_BASE_P(X) REG_OK_FOR_BASE_NONSTRICT_P(X)
00805 #else
00806 #define REG_OK_FOR_INDEX_P(X) REG_OK_FOR_INDEX_STRICT_P(X)
00807 #define REG_OK_FOR_BASE_P(X) REG_OK_FOR_BASE_STRICT_P(X)
00808 #endif
00809
00810
00811 #define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL)
00812
00813
00814
00815
00816
00817 #ifdef REG_OK_STRICT
00818 #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
00819 { \
00820 if (legitimate_address_p (MODE, X, 1)) \
00821 goto ADDR; \
00822 }
00823 #else
00824 #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
00825 { \
00826 if (legitimate_address_p (MODE, X, 0)) \
00827 goto ADDR; \
00828 }
00829 #endif
00830
00831
00832
00833
00834 #define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
00835 { \
00836 (X) = legitimize_address (X, OLDX, MODE); \
00837 if (memory_address_p (MODE, X)) \
00838 goto WIN; \
00839 }
00840
00841
00842
00843
00844 #define LEGITIMIZE_RELOAD_ADDRESS(AD, MODE, OPNUM, TYPE, IND, WIN) \
00845 do { \
00846 rtx new = legitimize_reload_address (AD, MODE, OPNUM, (int)(TYPE)); \
00847 if (new) \
00848 { \
00849 (AD) = new; \
00850 goto WIN; \
00851 } \
00852 } while (0)
00853
00854
00855
00856 #define LEGITIMATE_CONSTANT_P(X) \
00857 legitimate_constant_p (X)
00858
00859
00860 #define SYMBOLIC_CONST(X) \
00861 (GET_CODE (X) == SYMBOL_REF \
00862 || GET_CODE (X) == LABEL_REF \
00863 || (GET_CODE (X) == CONST && symbolic_reference_mentioned_p (X)))
00864
00865 #define TLS_SYMBOLIC_CONST(X) \
00866 ((GET_CODE (X) == SYMBOL_REF && tls_symbolic_operand (X)) \
00867 || (GET_CODE (X) == CONST && tls_symbolic_reference_mentioned_p (X)))
00868
00869
00870
00871
00872
00873
00874 #define SELECT_CC_MODE(OP, X, Y) s390_select_ccmode ((OP), (X), (Y))
00875
00876
00877 #define CANONICALIZE_COMPARISON(CODE, OP0, OP1) \
00878 s390_canonicalize_comparison (&(CODE), &(OP0), &(OP1))
00879
00880
00881
00882
00883 extern struct rtx_def *s390_compare_op0, *s390_compare_op1;
00884
00885
00886
00887
00888
00889 #define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \
00890 (( ( reg_classes_intersect_p ((CLASS1), GENERAL_REGS) \
00891 && reg_classes_intersect_p ((CLASS2), FP_REGS)) \
00892 || ( reg_classes_intersect_p ((CLASS1), FP_REGS) \
00893 && reg_classes_intersect_p ((CLASS2), GENERAL_REGS))) ? 10 : 1)
00894
00895
00896
00897
00898 #define MEMORY_MOVE_COST(M, C, I) 1
00899
00900
00901
00902 #define BRANCH_COST 1
00903
00904
00905 #define SLOW_BYTE_ACCESS 1
00906
00907
00908
00909 #define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (TARGET_64BIT ? TImode : DImode)
00910
00911
00912
00913 #define MOVE_MAX (TARGET_64BIT ? 16 : 8)
00914 #define MOVE_MAX_PIECES (TARGET_64BIT ? 8 : 4)
00915 #define MAX_MOVE_MAX 16
00916
00917
00918 #define MOVE_BY_PIECES_P(SIZE, ALIGN) \
00919 ( (SIZE) == 1 || (SIZE) == 2 || (SIZE) == 4 \
00920 || (TARGET_64BIT && (SIZE) == 8) )
00921
00922
00923 #define CLEAR_BY_PIECES_P(SIZE, ALIGN) \
00924 ( (SIZE) == 1 || (SIZE) == 2 || (SIZE) == 4 \
00925 || (TARGET_64BIT && (SIZE) == 8) )
00926
00927
00928
00929
00930 #define STORE_BY_PIECES_P(SIZE, ALIGN) MOVE_BY_PIECES_P (SIZE, ALIGN)
00931
00932
00933 #define NO_FUNCTION_CSE
00934
00935
00936
00937
00938
00939 #define TEXT_SECTION_ASM_OP ".text"
00940
00941
00942 #define DATA_SECTION_ASM_OP ".data"
00943
00944
00945 #define BSS_SECTION_ASM_OP ".bss"
00946
00947
00948
00949 #ifndef __s390x__
00950 #define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \
00951 asm (SECTION_OP "\n\
00952 bras\t%r2,1f\n\
00953 0: .long\t" USER_LABEL_PREFIX #FUNC " - 0b\n\
00954 1: l\t%r3,0(%r2)\n\
00955 bas\t%r14,0(%r3,%r2)\n\
00956 .previous");
00957 #endif
00958
00959
00960
00961
00962 extern int flag_pic;
00963
00964 #define PIC_OFFSET_TABLE_REGNUM (flag_pic ? 12 : INVALID_REGNUM)
00965
00966 #define LEGITIMATE_PIC_OPERAND_P(X) legitimate_pic_operand_p (X)
00967
00968
00969
00970
00971
00972 #define ASM_COMMENT_START "#"
00973
00974
00975 #define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
00976 asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
00977
00978
00979 #define GLOBAL_ASM_OP ".globl "
00980
00981
00982 #define ASM_OUTPUT_ALIGN(FILE, LOG) \
00983 if ((LOG)) fprintf ((FILE), "\t.align\t%d\n", 1 << (LOG))
00984
00985
00986 #define ASM_OUTPUT_SKIP(FILE, SIZE) \
00987 fprintf ((FILE), "\t.set\t.,.+"HOST_WIDE_INT_PRINT_UNSIGNED"\n", (SIZE))
00988
00989
00990 #define LOCAL_LABEL_PREFIX "."
00991
00992
00993
00994 #define REGISTER_NAMES \
00995 { "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7", \
00996 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", \
00997 "%f0", "%f2", "%f4", "%f6", "%f1", "%f3", "%f5", "%f7", \
00998 "%f8", "%f10", "%f12", "%f14", "%f9", "%f11", "%f13", "%f15", \
00999 "%ap", "%cc", "%fp", "%rp", "%a0", "%a1" \
01000 }
01001
01002
01003
01004 #ifdef HAVE_AS_TLS
01005 #define ASM_OUTPUT_DWARF_DTPREL(FILE, SIZE, X) \
01006 s390_output_dwarf_dtprel (FILE, SIZE, X)
01007 #endif
01008
01009
01010 #define PRINT_OPERAND(FILE, X, CODE) print_operand (FILE, X, CODE)
01011 #define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)
01012
01013
01014 #define OUTPUT_ADDR_CONST_EXTRA(FILE, X, FAIL) \
01015 do { \
01016 if (!s390_output_addr_const_extra (FILE, (X))) \
01017 goto FAIL; \
01018 } while (0);
01019
01020
01021 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
01022 do { \
01023 char buf[32]; \
01024 fputs (integer_asm_op (UNITS_PER_WORD, TRUE), (FILE)); \
01025 ASM_GENERATE_INTERNAL_LABEL (buf, "L", (VALUE)); \
01026 assemble_name ((FILE), buf); \
01027 fputc ('\n', (FILE)); \
01028 } while (0)
01029
01030
01031 #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
01032 do { \
01033 char buf[32]; \
01034 fputs (integer_asm_op (UNITS_PER_WORD, TRUE), (FILE)); \
01035 ASM_GENERATE_INTERNAL_LABEL (buf, "L", (VALUE)); \
01036 assemble_name ((FILE), buf); \
01037 fputc ('-', (FILE)); \
01038 ASM_GENERATE_INTERNAL_LABEL (buf, "L", (REL)); \
01039 assemble_name ((FILE), buf); \
01040 fputc ('\n', (FILE)); \
01041 } while (0)
01042
01043
01044
01045
01046
01047 #define PREDICATE_CODES \
01048 {"s_operand", { SUBREG, MEM }}, \
01049 {"shift_count_operand", { REG, SUBREG, PLUS, CONST_INT }}, \
01050 {"bras_sym_operand",{ SYMBOL_REF, CONST }}, \
01051 {"larl_operand", { SYMBOL_REF, CONST, CONST_INT, CONST_DOUBLE }}, \
01052 {"load_multiple_operation", {PARALLEL}}, \
01053 {"store_multiple_operation", {PARALLEL}}, \
01054 {"const0_operand", { CONST_INT, CONST_DOUBLE }}, \
01055 {"consttable_operand", { SYMBOL_REF, LABEL_REF, CONST, \
01056 CONST_INT, CONST_DOUBLE }}, \
01057 {"s390_plus_operand", { PLUS }}, \
01058 {"s390_comparison", { EQ, NE, LT, GT, LE, GE, LTU, GTU, LEU, GEU, \
01059 UNEQ, UNLT, UNGT, UNLE, UNGE, LTGT, \
01060 UNORDERED, ORDERED }}, \
01061 {"s390_alc_comparison", { ZERO_EXTEND, SIGN_EXTEND, \
01062 LTU, GTU, LEU, GEU }}, \
01063 {"s390_slb_comparison", { ZERO_EXTEND, SIGN_EXTEND, \
01064 LTU, GTU, LEU, GEU }},
01065
01066
01067
01068 #define CASE_VECTOR_MODE (TARGET_64BIT ? DImode : SImode)
01069
01070
01071
01072 #define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
01073
01074
01075
01076
01077 #define Pmode ((enum machine_mode) (TARGET_64BIT ? DImode : SImode))
01078
01079
01080 #define POINTERS_EXTEND_UNSIGNED -1
01081
01082
01083
01084 #define FUNCTION_MODE QImode
01085
01086 #endif