00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef GCC_ARM_H
00027 #define GCC_ARM_H
00028
00029 #define TARGET_CPU_arm2 0x0000
00030 #define TARGET_CPU_arm250 0x0000
00031 #define TARGET_CPU_arm3 0x0000
00032 #define TARGET_CPU_arm6 0x0001
00033 #define TARGET_CPU_arm600 0x0001
00034 #define TARGET_CPU_arm610 0x0002
00035 #define TARGET_CPU_arm7 0x0001
00036 #define TARGET_CPU_arm7m 0x0004
00037 #define TARGET_CPU_arm7dm 0x0004
00038 #define TARGET_CPU_arm7dmi 0x0004
00039 #define TARGET_CPU_arm700 0x0001
00040 #define TARGET_CPU_arm710 0x0002
00041 #define TARGET_CPU_arm7100 0x0002
00042 #define TARGET_CPU_arm7500 0x0002
00043 #define TARGET_CPU_arm7500fe 0x1001
00044 #define TARGET_CPU_arm7tdmi 0x0008
00045 #define TARGET_CPU_arm8 0x0010
00046 #define TARGET_CPU_arm810 0x0020
00047 #define TARGET_CPU_strongarm 0x0040
00048 #define TARGET_CPU_strongarm110 0x0040
00049 #define TARGET_CPU_strongarm1100 0x0040
00050 #define TARGET_CPU_arm9 0x0080
00051 #define TARGET_CPU_arm9tdmi 0x0080
00052 #define TARGET_CPU_xscale 0x0100
00053
00054 #define TARGET_CPU_generic 0x8000
00055
00056 typedef enum arm_cond_code
00057 {
00058 ARM_EQ = 0, ARM_NE, ARM_CS, ARM_CC, ARM_MI, ARM_PL, ARM_VS, ARM_VC,
00059 ARM_HI, ARM_LS, ARM_GE, ARM_LT, ARM_GT, ARM_LE, ARM_AL, ARM_NV
00060 }
00061 arm_cc;
00062
00063 extern arm_cc arm_current_cc;
00064
00065 #define ARM_INVERSE_CONDITION_CODE(X) ((arm_cc) (((int)X) ^ 1))
00066
00067 extern int arm_target_label;
00068 extern int arm_ccfsm_state;
00069 extern struct rtx_def * arm_target_insn;
00070
00071 extern int target_flags;
00072
00073 extern const char * target_fp_name;
00074
00075
00076
00077 extern struct rtx_def * arm_compare_op0;
00078 extern struct rtx_def * arm_compare_op1;
00079
00080 extern struct rtx_def * pool_vector_label;
00081
00082
00083 extern int return_used_this_function;
00084
00085
00086 #ifndef TARGET_CPU_DEFAULT
00087 #define TARGET_CPU_DEFAULT TARGET_CPU_generic
00088 #endif
00089
00090
00091
00092 #if TARGET_CPU_DEFAULT == TARGET_CPU_generic
00093 #undef TARGET_CPU_DEFAULT
00094
00095 #ifdef SUBTARGET_CPU_DEFAULT
00096 #define TARGET_CPU_DEFAULT SUBTARGET_CPU_DEFAULT
00097 #else
00098 #define TARGET_CPU_DEFAULT TARGET_CPU_arm6
00099 #endif
00100 #endif
00101
00102 #if TARGET_CPU_DEFAULT == TARGET_CPU_arm2
00103 #define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_2__"
00104 #else
00105 #if TARGET_CPU_DEFAULT == TARGET_CPU_arm6 || TARGET_CPU_DEFAULT == TARGET_CPU_arm610 || TARGET_CPU_DEFAULT == TARGET_CPU_arm7500fe
00106 #define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_3__"
00107 #else
00108 #if TARGET_CPU_DEFAULT == TARGET_CPU_arm7m
00109 #define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_3M__"
00110 #else
00111 #if TARGET_CPU_DEFAULT == TARGET_CPU_arm7tdmi || TARGET_CPU_DEFAULT == TARGET_CPU_arm9 || TARGET_CPU_DEFAULT == TARGET_CPU_arm9tdmi
00112 #define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_4T__"
00113 #else
00114 #if TARGET_CPU_DEFAULT == TARGET_CPU_arm8 || TARGET_CPU_DEFAULT == TARGET_CPU_arm810 || TARGET_CPU_DEFAULT == TARGET_CPU_strongarm || TARGET_CPU_DEFAULT == TARGET_CPU_strongarm110 || TARGET_CPU_DEFAULT == TARGET_CPU_strongarm1100
00115 #define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_4__"
00116 #else
00117 #if TARGET_CPU_DEFAULT == TARGET_CPU_xscale
00118 #define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_5TE__ -D__XSCALE__"
00119 #else
00120 Unrecognized value in TARGET_CPU_DEFAULT.
00121 #endif
00122 #endif
00123 #endif
00124 #endif
00125 #endif
00126 #endif
00127
00128 #undef CPP_SPEC
00129 #define CPP_SPEC "\
00130 %(cpp_cpu_arch) %(cpp_apcs_pc) %(cpp_float) \
00131 %(cpp_endian) %(subtarget_cpp_spec) %(cpp_isa) %(cpp_interwork)"
00132
00133 #define CPP_ISA_SPEC "%{mthumb:-D__thumb__} %{!mthumb:-D__arm__}"
00134
00135
00136
00137 #define CPP_CPU_ARCH_SPEC "\
00138 -Acpu=arm -Amachine=arm \
00139 %{march=arm2:-D__ARM_ARCH_2__} \
00140 %{march=arm250:-D__ARM_ARCH_2__} \
00141 %{march=arm3:-D__ARM_ARCH_2__} \
00142 %{march=arm6:-D__ARM_ARCH_3__} \
00143 %{march=arm600:-D__ARM_ARCH_3__} \
00144 %{march=arm610:-D__ARM_ARCH_3__} \
00145 %{march=arm7:-D__ARM_ARCH_3__} \
00146 %{march=arm700:-D__ARM_ARCH_3__} \
00147 %{march=arm710:-D__ARM_ARCH_3__} \
00148 %{march=arm720:-D__ARM_ARCH_3__} \
00149 %{march=arm7100:-D__ARM_ARCH_3__} \
00150 %{march=arm7500:-D__ARM_ARCH_3__} \
00151 %{march=arm7500fe:-D__ARM_ARCH_3__} \
00152 %{march=arm7m:-D__ARM_ARCH_3M__} \
00153 %{march=arm7dm:-D__ARM_ARCH_3M__} \
00154 %{march=arm7dmi:-D__ARM_ARCH_3M__} \
00155 %{march=arm7tdmi:-D__ARM_ARCH_4T__} \
00156 %{march=arm8:-D__ARM_ARCH_4__} \
00157 %{march=arm810:-D__ARM_ARCH_4__} \
00158 %{march=arm9:-D__ARM_ARCH_4T__} \
00159 %{march=arm920:-D__ARM_ARCH_4__} \
00160 %{march=arm920t:-D__ARM_ARCH_4T__} \
00161 %{march=arm9tdmi:-D__ARM_ARCH_4T__} \
00162 %{march=strongarm:-D__ARM_ARCH_4__} \
00163 %{march=strongarm110:-D__ARM_ARCH_4__} \
00164 %{march=strongarm1100:-D__ARM_ARCH_4__} \
00165 %{march=xscale:-D__ARM_ARCH_5TE__} \
00166 %{march=xscale:-D__XSCALE__} \
00167 %{march=armv2:-D__ARM_ARCH_2__} \
00168 %{march=armv2a:-D__ARM_ARCH_2__} \
00169 %{march=armv3:-D__ARM_ARCH_3__} \
00170 %{march=armv3m:-D__ARM_ARCH_3M__} \
00171 %{march=armv4:-D__ARM_ARCH_4__} \
00172 %{march=armv4t:-D__ARM_ARCH_4T__} \
00173 %{march=armv5:-D__ARM_ARCH_5__} \
00174 %{march=armv5t:-D__ARM_ARCH_5T__} \
00175 %{march=armv5e:-D__ARM_ARCH_5E__} \
00176 %{march=armv5te:-D__ARM_ARCH_5TE__} \
00177 %{!march=*: \
00178 %{mcpu=arm2:-D__ARM_ARCH_2__} \
00179 %{mcpu=arm250:-D__ARM_ARCH_2__} \
00180 %{mcpu=arm3:-D__ARM_ARCH_2__} \
00181 %{mcpu=arm6:-D__ARM_ARCH_3__} \
00182 %{mcpu=arm600:-D__ARM_ARCH_3__} \
00183 %{mcpu=arm610:-D__ARM_ARCH_3__} \
00184 %{mcpu=arm7:-D__ARM_ARCH_3__} \
00185 %{mcpu=arm700:-D__ARM_ARCH_3__} \
00186 %{mcpu=arm710:-D__ARM_ARCH_3__} \
00187 %{mcpu=arm720:-D__ARM_ARCH_3__} \
00188 %{mcpu=arm7100:-D__ARM_ARCH_3__} \
00189 %{mcpu=arm7500:-D__ARM_ARCH_3__} \
00190 %{mcpu=arm7500fe:-D__ARM_ARCH_3__} \
00191 %{mcpu=arm7m:-D__ARM_ARCH_3M__} \
00192 %{mcpu=arm7dm:-D__ARM_ARCH_3M__} \
00193 %{mcpu=arm7dmi:-D__ARM_ARCH_3M__} \
00194 %{mcpu=arm7tdmi:-D__ARM_ARCH_4T__} \
00195 %{mcpu=arm8:-D__ARM_ARCH_4__} \
00196 %{mcpu=arm810:-D__ARM_ARCH_4__} \
00197 %{mcpu=arm9:-D__ARM_ARCH_4T__} \
00198 %{mcpu=arm920:-D__ARM_ARCH_4__} \
00199 %{mcpu=arm920t:-D__ARM_ARCH_4T__} \
00200 %{mcpu=arm9tdmi:-D__ARM_ARCH_4T__} \
00201 %{mcpu=strongarm:-D__ARM_ARCH_4__} \
00202 %{mcpu=strongarm110:-D__ARM_ARCH_4__} \
00203 %{mcpu=strongarm1100:-D__ARM_ARCH_4__} \
00204 %{mcpu=xscale:-D__ARM_ARCH_5TE__} \
00205 %{mcpu=xscale:-D__XSCALE__} \
00206 %{!mcpu*:%(cpp_cpu_arch_default)}} \
00207 "
00208
00209
00210 #define CPP_APCS_PC_SPEC "\
00211 %{mapcs-32:%{mapcs-26:%e-mapcs-26 and -mapcs-32 may not be used together} \
00212 -D__APCS_32__} \
00213 %{mapcs-26:-D__APCS_26__} \
00214 %{!mapcs-32: %{!mapcs-26:%(cpp_apcs_pc_default)}} \
00215 "
00216
00217 #ifndef CPP_APCS_PC_DEFAULT_SPEC
00218 #define CPP_APCS_PC_DEFAULT_SPEC "-D__APCS_26__"
00219 #endif
00220
00221 #define CPP_FLOAT_SPEC "\
00222 %{msoft-float:\
00223 %{mhard-float:%e-msoft-float and -mhard_float may not be used together} \
00224 -D__SOFTFP__} \
00225 %{!mhard-float:%{!msoft-float:%(cpp_float_default)}} \
00226 "
00227
00228
00229 #define CPP_FLOAT_DEFAULT_SPEC ""
00230
00231 #define CPP_ENDIAN_SPEC "\
00232 %{mbig-endian: \
00233 %{mlittle-endian: \
00234 %e-mbig-endian and -mlittle-endian may not be used together} \
00235 -D__ARMEB__ %{mwords-little-endian:-D__ARMWEL__} %{mthumb:-D__THUMBEB__}}\
00236 %{mlittle-endian:-D__ARMEL__ %{mthumb:-D__THUMBEL__}} \
00237 %{!mlittle-endian:%{!mbig-endian:%(cpp_endian_default)}} \
00238 "
00239
00240
00241 #define CPP_ENDIAN_DEFAULT_SPEC "-D__ARMEL__ %{mthumb:-D__THUMBEL__}"
00242
00243
00244
00245
00246 #ifndef CPP_INTERWORK_DEFAULT_SPEC
00247 #define CPP_INTERWORK_DEFAULT_SPEC ""
00248 #endif
00249
00250 #define CPP_INTERWORK_SPEC " \
00251 %{mthumb-interwork: \
00252 %{mno-thumb-interwork: %eincompatible interworking options} \
00253 -D__THUMB_INTERWORK__} \
00254 %{!mthumb-interwork:%{!mno-thumb-interwork:%(cpp_interwork_default)}} \
00255 "
00256
00257 #ifndef CPP_PREDEFINES
00258 #define CPP_PREDEFINES ""
00259 #endif
00260
00261 #ifndef CC1_SPEC
00262 #define CC1_SPEC ""
00263 #endif
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274 #define EXTRA_SPECS \
00275 { "cpp_cpu_arch", CPP_CPU_ARCH_SPEC }, \
00276 { "cpp_cpu_arch_default", CPP_ARCH_DEFAULT_SPEC }, \
00277 { "cpp_apcs_pc", CPP_APCS_PC_SPEC }, \
00278 { "cpp_apcs_pc_default", CPP_APCS_PC_DEFAULT_SPEC }, \
00279 { "cpp_float", CPP_FLOAT_SPEC }, \
00280 { "cpp_float_default", CPP_FLOAT_DEFAULT_SPEC }, \
00281 { "cpp_endian", CPP_ENDIAN_SPEC }, \
00282 { "cpp_endian_default", CPP_ENDIAN_DEFAULT_SPEC }, \
00283 { "cpp_isa", CPP_ISA_SPEC }, \
00284 { "cpp_interwork", CPP_INTERWORK_SPEC }, \
00285 { "cpp_interwork_default", CPP_INTERWORK_DEFAULT_SPEC }, \
00286 { "subtarget_cpp_spec", SUBTARGET_CPP_SPEC }, \
00287 SUBTARGET_EXTRA_SPECS
00288
00289 #ifndef SUBTARGET_EXTRA_SPECS
00290 #define SUBTARGET_EXTRA_SPECS
00291 #endif
00292
00293 #ifndef SUBTARGET_CPP_SPEC
00294 #define SUBTARGET_CPP_SPEC ""
00295 #endif
00296
00297
00298 #ifndef TARGET_VERSION
00299 #define TARGET_VERSION fputs (" (ARM/generic)", stderr);
00300 #endif
00301
00302
00303
00304 #define ARM_FLAG_APCS_FRAME (1 << 0)
00305
00306
00307
00308
00309
00310
00311 #define ARM_FLAG_POKE (1 << 1)
00312
00313
00314
00315 #define ARM_FLAG_FPE (1 << 2)
00316
00317
00318
00319
00320 #define ARM_FLAG_APCS_32 (1 << 3)
00321
00322
00323
00324
00325
00326 #define ARM_FLAG_APCS_STACK (1 << 4)
00327
00328
00329
00330 #define ARM_FLAG_APCS_FLOAT (1 << 5)
00331
00332
00333
00334 #define ARM_FLAG_APCS_REENT (1 << 6)
00335
00336
00337
00338 #define ARM_FLAG_MMU_TRAPS (1 << 7)
00339
00340
00341
00342 #define ARM_FLAG_SOFT_FLOAT (1 << 8)
00343
00344
00345 #define ARM_FLAG_BIG_END (1 << 9)
00346
00347
00348 #define ARM_FLAG_INTERWORK (1 << 10)
00349
00350
00351
00352 #define ARM_FLAG_LITTLE_WORDS (1 << 11)
00353
00354
00355 #define ARM_FLAG_NO_SCHED_PRO (1 << 12)
00356
00357
00358
00359 #define ARM_FLAG_ABORT_NORETURN (1 << 13)
00360
00361
00362 #define ARM_FLAG_SINGLE_PIC_BASE (1 << 14)
00363
00364
00365 #define ARM_FLAG_LONG_CALLS (1 << 15)
00366
00367
00368 #define ARM_FLAG_THUMB (1 << 16)
00369
00370
00371
00372 #define THUMB_FLAG_BACKTRACE (1 << 17)
00373
00374
00375
00376 #define THUMB_FLAG_LEAF_BACKTRACE (1 << 18)
00377
00378
00379
00380 #define THUMB_FLAG_CALLEE_SUPER_INTERWORKING (1 << 19)
00381
00382
00383
00384 #define THUMB_FLAG_CALLER_SUPER_INTERWORKING (1 << 20)
00385
00386 #define TARGET_APCS_FRAME (target_flags & ARM_FLAG_APCS_FRAME)
00387 #define TARGET_POKE_FUNCTION_NAME (target_flags & ARM_FLAG_POKE)
00388 #define TARGET_FPE (target_flags & ARM_FLAG_FPE)
00389 #define TARGET_APCS_32 (target_flags & ARM_FLAG_APCS_32)
00390 #define TARGET_APCS_STACK (target_flags & ARM_FLAG_APCS_STACK)
00391 #define TARGET_APCS_FLOAT (target_flags & ARM_FLAG_APCS_FLOAT)
00392 #define TARGET_APCS_REENT (target_flags & ARM_FLAG_APCS_REENT)
00393 #define TARGET_MMU_TRAPS (target_flags & ARM_FLAG_MMU_TRAPS)
00394 #define TARGET_SOFT_FLOAT (target_flags & ARM_FLAG_SOFT_FLOAT)
00395 #define TARGET_HARD_FLOAT (! TARGET_SOFT_FLOAT)
00396 #define TARGET_BIG_END (target_flags & ARM_FLAG_BIG_END)
00397 #define TARGET_INTERWORK (target_flags & ARM_FLAG_INTERWORK)
00398 #define TARGET_LITTLE_WORDS (target_flags & ARM_FLAG_LITTLE_WORDS)
00399 #define TARGET_NO_SCHED_PRO (target_flags & ARM_FLAG_NO_SCHED_PRO)
00400 #define TARGET_ABORT_NORETURN (target_flags & ARM_FLAG_ABORT_NORETURN)
00401 #define TARGET_SINGLE_PIC_BASE (target_flags & ARM_FLAG_SINGLE_PIC_BASE)
00402 #define TARGET_LONG_CALLS (target_flags & ARM_FLAG_LONG_CALLS)
00403 #define TARGET_THUMB (target_flags & ARM_FLAG_THUMB)
00404 #define TARGET_ARM (! TARGET_THUMB)
00405 #define TARGET_EITHER 1
00406 #define TARGET_CALLEE_INTERWORKING (target_flags & THUMB_FLAG_CALLEE_SUPER_INTERWORKING)
00407 #define TARGET_CALLER_INTERWORKING (target_flags & THUMB_FLAG_CALLER_SUPER_INTERWORKING)
00408 #define TARGET_BACKTRACE (leaf_function_p () \
00409 ? (target_flags & THUMB_FLAG_LEAF_BACKTRACE) \
00410 : (target_flags & THUMB_FLAG_BACKTRACE))
00411
00412
00413
00414 #ifndef SUBTARGET_SWITCHES
00415 #define SUBTARGET_SWITCHES
00416 #endif
00417
00418 #define TARGET_SWITCHES \
00419 { \
00420 {"apcs", ARM_FLAG_APCS_FRAME, "" }, \
00421 {"apcs-frame", ARM_FLAG_APCS_FRAME, \
00422 N_("Generate APCS conformant stack frames") }, \
00423 {"no-apcs-frame", -ARM_FLAG_APCS_FRAME, "" }, \
00424 {"poke-function-name", ARM_FLAG_POKE, \
00425 N_("Store function names in object code") }, \
00426 {"no-poke-function-name", -ARM_FLAG_POKE, "" }, \
00427 {"fpe", ARM_FLAG_FPE, "" }, \
00428 {"apcs-32", ARM_FLAG_APCS_32, \
00429 N_("Use the 32-bit version of the APCS") }, \
00430 {"apcs-26", -ARM_FLAG_APCS_32, \
00431 N_("Use the 26-bit version of the APCS") }, \
00432 {"apcs-stack-check", ARM_FLAG_APCS_STACK, "" }, \
00433 {"no-apcs-stack-check", -ARM_FLAG_APCS_STACK, "" }, \
00434 {"apcs-float", ARM_FLAG_APCS_FLOAT, \
00435 N_("Pass FP arguments in FP registers") }, \
00436 {"no-apcs-float", -ARM_FLAG_APCS_FLOAT, "" }, \
00437 {"apcs-reentrant", ARM_FLAG_APCS_REENT, \
00438 N_("Generate re-entrant, PIC code") }, \
00439 {"no-apcs-reentrant", -ARM_FLAG_APCS_REENT, "" }, \
00440 {"alignment-traps", ARM_FLAG_MMU_TRAPS, \
00441 N_("The MMU will trap on unaligned accesses") }, \
00442 {"no-alignment-traps", -ARM_FLAG_MMU_TRAPS, "" }, \
00443 {"short-load-bytes", ARM_FLAG_MMU_TRAPS, "" }, \
00444 {"no-short-load-bytes", -ARM_FLAG_MMU_TRAPS, "" }, \
00445 {"short-load-words", -ARM_FLAG_MMU_TRAPS, "" }, \
00446 {"no-short-load-words", ARM_FLAG_MMU_TRAPS, "" }, \
00447 {"soft-float", ARM_FLAG_SOFT_FLOAT, \
00448 N_("Use library calls to perform FP operations") }, \
00449 {"hard-float", -ARM_FLAG_SOFT_FLOAT, \
00450 N_("Use hardware floating point instructions") }, \
00451 {"big-endian", ARM_FLAG_BIG_END, \
00452 N_("Assume target CPU is configured as big endian") }, \
00453 {"little-endian", -ARM_FLAG_BIG_END, \
00454 N_("Assume target CPU is configured as little endian") }, \
00455 {"words-little-endian", ARM_FLAG_LITTLE_WORDS, \
00456 N_("Assume big endian bytes, little endian words") }, \
00457 {"thumb-interwork", ARM_FLAG_INTERWORK, \
00458 N_("Support calls between Thumb and ARM instruction sets") }, \
00459 {"no-thumb-interwork", -ARM_FLAG_INTERWORK, "" }, \
00460 {"abort-on-noreturn", ARM_FLAG_ABORT_NORETURN, \
00461 N_("Generate a call to abort if a noreturn function returns")}, \
00462 {"no-abort-on-noreturn", -ARM_FLAG_ABORT_NORETURN, "" }, \
00463 {"no-sched-prolog", ARM_FLAG_NO_SCHED_PRO, \
00464 N_("Do not move instructions into a function's prologue") }, \
00465 {"sched-prolog", -ARM_FLAG_NO_SCHED_PRO, "" }, \
00466 {"single-pic-base", ARM_FLAG_SINGLE_PIC_BASE, \
00467 N_("Do not load the PIC register in function prologues") }, \
00468 {"no-single-pic-base", -ARM_FLAG_SINGLE_PIC_BASE, "" }, \
00469 {"long-calls", ARM_FLAG_LONG_CALLS, \
00470 N_("Generate call insns as indirect calls, if necessary") }, \
00471 {"no-long-calls", -ARM_FLAG_LONG_CALLS, "" }, \
00472 {"thumb", ARM_FLAG_THUMB, \
00473 N_("Compile for the Thumb not the ARM") }, \
00474 {"no-thumb", -ARM_FLAG_THUMB, "" }, \
00475 {"arm", -ARM_FLAG_THUMB, "" }, \
00476 {"tpcs-frame", THUMB_FLAG_BACKTRACE, \
00477 N_("Thumb: Generate (non-leaf) stack frames even if not needed") }, \
00478 {"no-tpcs-frame", -THUMB_FLAG_BACKTRACE, "" }, \
00479 {"tpcs-leaf-frame", THUMB_FLAG_LEAF_BACKTRACE, \
00480 N_("Thumb: Generate (leaf) stack frames even if not needed") }, \
00481 {"no-tpcs-leaf-frame", -THUMB_FLAG_LEAF_BACKTRACE, "" }, \
00482 {"callee-super-interworking", THUMB_FLAG_CALLEE_SUPER_INTERWORKING, \
00483 N_("Thumb: Assume non-static functions may be called from ARM code") }, \
00484 {"no-callee-super-interworking", -THUMB_FLAG_CALLEE_SUPER_INTERWORKING, \
00485 "" }, \
00486 {"caller-super-interworking", THUMB_FLAG_CALLER_SUPER_INTERWORKING, \
00487 N_("Thumb: Assume function pointers may go to non-Thumb aware code") }, \
00488 {"no-caller-super-interworking", -THUMB_FLAG_CALLER_SUPER_INTERWORKING, \
00489 "" }, \
00490 SUBTARGET_SWITCHES \
00491 {"", TARGET_DEFAULT, "" } \
00492 }
00493
00494 #define TARGET_OPTIONS \
00495 { \
00496 {"cpu=", & arm_select[0].string, \
00497 N_("Specify the name of the target CPU") }, \
00498 {"arch=", & arm_select[1].string, \
00499 N_("Specify the name of the target architecture") }, \
00500 {"tune=", & arm_select[2].string, "" }, \
00501 {"fpe=", & target_fp_name, "" }, \
00502 {"fp=", & target_fp_name, \
00503 N_("Specify the version of the floating point emulator") }, \
00504 {"structure-size-boundary=", & structure_size_string, \
00505 N_("Specify the minimum bit alignment of structures") }, \
00506 {"pic-register=", & arm_pic_register_string, \
00507 N_("Specify the register to be used for PIC addressing") } \
00508 }
00509
00510 struct arm_cpu_select
00511 {
00512 const char * string;
00513 const char * name;
00514 const struct processors * processors;
00515 };
00516
00517
00518
00519
00520 extern struct arm_cpu_select arm_select[];
00521
00522 enum prog_mode_type
00523 {
00524 prog_mode26,
00525 prog_mode32
00526 };
00527
00528
00529 #define arm_prog_mode ((enum attr_prog_mode) arm_prgmode)
00530
00531 extern enum prog_mode_type arm_prgmode;
00532
00533
00534
00535 enum floating_point_type
00536 {
00537 FP_HARD,
00538 FP_SOFT2,
00539 FP_SOFT3
00540 };
00541
00542
00543 #define arm_fpu_attr ((enum attr_fpu) arm_fpu)
00544
00545
00546 extern enum floating_point_type arm_fpu;
00547
00548
00549 extern enum floating_point_type arm_fpu_arch;
00550
00551
00552
00553 #ifndef FP_DEFAULT
00554 #define FP_DEFAULT FP_SOFT2
00555 #endif
00556
00557
00558
00559 extern int arm_fast_multiply;
00560
00561
00562 extern int arm_arch4;
00563
00564
00565 extern int arm_arch5;
00566
00567
00568 extern int arm_arch5e;
00569
00570
00571 extern int arm_ld_sched;
00572
00573
00574 extern int thumb_code;
00575
00576
00577 extern int arm_is_strong;
00578
00579
00580 extern int arm_is_xscale;
00581
00582
00583 extern int arm_is_6_or_7;
00584
00585 #ifndef TARGET_DEFAULT
00586 #define TARGET_DEFAULT (ARM_FLAG_APCS_FRAME)
00587 #endif
00588
00589
00590
00591 #define CAN_DEBUG_WITHOUT_FP
00592
00593 #undef TARGET_MEM_FUNCTIONS
00594 #define TARGET_MEM_FUNCTIONS 1
00595
00596 #define OVERRIDE_OPTIONS arm_override_options ()
00597
00598
00599
00600
00601 #ifndef NEED_GOT_RELOC
00602 #define NEED_GOT_RELOC 0
00603 #endif
00604 #ifndef NEED_PLT_RELOC
00605 #define NEED_PLT_RELOC 0
00606 #endif
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619 #ifndef GOT_PCREL
00620 #define GOT_PCREL 1
00621 #endif
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634 #define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \
00635 if (GET_MODE_CLASS (MODE) == MODE_INT \
00636 && GET_MODE_SIZE (MODE) < 4) \
00637 { \
00638 if (MODE == QImode) \
00639 UNSIGNEDP = 1; \
00640 else if (MODE == HImode) \
00641 UNSIGNEDP = TARGET_MMU_TRAPS != 0; \
00642 (MODE) = SImode; \
00643 }
00644
00645
00646
00647
00648 #define PROMOTE_FUNCTION_ARGS
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664 #define ENABLE_XF_PATTERNS 0
00665
00666
00667
00668
00669
00670 #define REAL_ARITHMETIC
00671
00672
00673
00674 #define BITS_BIG_ENDIAN 0
00675
00676
00677
00678
00679
00680 #define BYTES_BIG_ENDIAN (TARGET_BIG_END != 0)
00681
00682
00683
00684
00685 #define WORDS_BIG_ENDIAN (BYTES_BIG_ENDIAN && ! TARGET_LITTLE_WORDS)
00686
00687
00688
00689 #if defined(__ARMEB__) && !defined(__ARMWEL__)
00690 #define LIBGCC2_WORDS_BIG_ENDIAN 1
00691 #else
00692 #define LIBGCC2_WORDS_BIG_ENDIAN 0
00693 #endif
00694
00695
00696
00697 #define FLOAT_WORDS_BIG_ENDIAN 1
00698
00699
00700 #define BITS_PER_UNIT 8
00701
00702 #define BITS_PER_WORD 32
00703
00704 #define UNITS_PER_WORD 4
00705
00706 #define POINTER_SIZE 32
00707
00708 #define PARM_BOUNDARY 32
00709
00710 #define STACK_BOUNDARY 32
00711
00712 #define FUNCTION_BOUNDARY 32
00713
00714
00715
00716
00717 #define TARGET_PTRMEMFUNC_VBIT_LOCATION ptrmemfunc_vbit_in_delta
00718
00719 #define EMPTY_FIELD_BOUNDARY 32
00720
00721 #define BIGGEST_ALIGNMENT 32
00722
00723
00724 #define CONSTANT_ALIGNMENT_FACTOR (TARGET_THUMB || ! arm_is_xscale ? 1 : 2)
00725
00726 #define CONSTANT_ALIGNMENT(EXP, ALIGN) \
00727 ((TREE_CODE (EXP) == STRING_CST \
00728 && (ALIGN) < BITS_PER_WORD * CONSTANT_ALIGNMENT_FACTOR) \
00729 ? BITS_PER_WORD * CONSTANT_ALIGNMENT_FACTOR : (ALIGN))
00730
00731
00732
00733
00734
00735
00736
00737 #define STRUCTURE_SIZE_BOUNDARY arm_structure_size_boundary
00738 extern int arm_structure_size_boundary;
00739
00740
00741
00742
00743
00744 #ifndef DEFAULT_STRUCTURE_SIZE_BOUNDARY
00745 #define DEFAULT_STRUCTURE_SIZE_BOUNDARY 32
00746 #endif
00747
00748
00749 extern const char * structure_size_string;
00750
00751
00752
00753 #define STRICT_ALIGNMENT 1
00754
00755 #define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818 #define FIXED_REGISTERS \
00819 { \
00820 0,0,0,0,0,0,0,0, \
00821 0,0,0,0,0,1,0,1, \
00822 0,0,0,0,0,0,0,0, \
00823 1,1,1 \
00824 }
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834 #define CALL_USED_REGISTERS \
00835 { \
00836 1,1,1,1,0,0,0,0, \
00837 0,0,0,0,1,1,1,1, \
00838 1,1,1,1,0,0,0,0, \
00839 1,1,1 \
00840 }
00841
00842 #ifndef SUBTARGET_CONDITIONAL_REGISTER_USAGE
00843 #define SUBTARGET_CONDITIONAL_REGISTER_USAGE
00844 #endif
00845
00846 #define CONDITIONAL_REGISTER_USAGE \
00847 { \
00848 int regno; \
00849 \
00850 if (TARGET_SOFT_FLOAT || TARGET_THUMB) \
00851 { \
00852 for (regno = FIRST_ARM_FP_REGNUM; \
00853 regno <= LAST_ARM_FP_REGNUM; ++regno) \
00854 fixed_regs[regno] = call_used_regs[regno] = 1; \
00855 } \
00856 if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) \
00857 { \
00858 fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
00859 call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
00860 } \
00861 else if (TARGET_APCS_STACK) \
00862 { \
00863 fixed_regs[10] = 1; \
00864 call_used_regs[10] = 1; \
00865 } \
00866 if (TARGET_APCS_FRAME) \
00867 { \
00868 fixed_regs[ARM_HARD_FRAME_POINTER_REGNUM] = 1; \
00869 call_used_regs[ARM_HARD_FRAME_POINTER_REGNUM] = 1; \
00870 } \
00871 SUBTARGET_CONDITIONAL_REGISTER_USAGE \
00872 }
00873
00874
00875
00876
00877
00878 #define ASM_FPRINTF_EXTENSIONS(FILE, ARGS, P) \
00879 case '@': \
00880 fputs (ASM_COMMENT_START, FILE); \
00881 break; \
00882 \
00883 case 'r': \
00884 fputs (REGISTER_PREFIX, FILE); \
00885 fputs (reg_names [va_arg (ARGS, int)], FILE); \
00886 break;
00887
00888
00889 #define ROUND_UP(X) (((X) + 3) & ~3)
00890
00891
00892 #define NUM_INTS(X) (((X) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
00893
00894
00895 #define NUM_REGS(MODE) \
00896 NUM_INTS (GET_MODE_SIZE (MODE))
00897
00898
00899 #define NUM_REGS2(MODE, TYPE) \
00900 NUM_INTS ((MODE) == BLKmode ? \
00901 int_size_in_bytes (TYPE) : GET_MODE_SIZE (MODE))
00902
00903
00904 #define NUM_ARG_REGS 4
00905
00906
00907 #define ARG_REGISTER(N) (N - 1)
00908
00909 #if 0
00910
00911
00912
00913
00914
00915
00916 #define STRUCT_VALUE 0
00917 #else
00918
00919
00920 #define STRUCT_VALUE_REGNUM ARG_REGISTER (1)
00921 #endif
00922
00923
00924
00925
00926
00927 #define LAST_ARG_REGNUM ARG_REGISTER (NUM_ARG_REGS)
00928
00929
00930 #define LAST_LO_REGNUM 7
00931
00932
00933 #define EXCEPTION_LR_REGNUM 2
00934
00935
00936
00937
00938 #define STATIC_CHAIN_REGNUM (TARGET_ARM ? 12 : 9)
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956 #define ARM_HARD_FRAME_POINTER_REGNUM 11
00957 #define THUMB_HARD_FRAME_POINTER_REGNUM 7
00958
00959 #define HARD_FRAME_POINTER_REGNUM \
00960 (TARGET_ARM \
00961 ? ARM_HARD_FRAME_POINTER_REGNUM \
00962 : THUMB_HARD_FRAME_POINTER_REGNUM)
00963
00964 #define FP_REGNUM HARD_FRAME_POINTER_REGNUM
00965
00966
00967 #define STACK_POINTER_REGNUM SP_REGNUM
00968
00969
00970 #define FIRST_ARM_FP_REGNUM 16
00971 #define LAST_ARM_FP_REGNUM 23
00972
00973
00974 #define FRAME_POINTER_REGNUM 25
00975
00976
00977 #define ARG_POINTER_REGNUM 26
00978
00979
00980 #define FIRST_PSEUDO_REGISTER 27
00981
00982
00983
00984
00985
00986
00987
00988 #define FRAME_POINTER_REQUIRED \
00989 (current_function_has_nonlocal_label \
00990 || (TARGET_ARM && TARGET_APCS_FRAME && ! leaf_function_p ()))
00991
00992
00993
00994
00995
00996
00997
00998
00999 #define HARD_REGNO_NREGS(REGNO, MODE) \
01000 ((TARGET_ARM \
01001 && REGNO >= FIRST_ARM_FP_REGNUM \
01002 && REGNO != FRAME_POINTER_REGNUM \
01003 && REGNO != ARG_POINTER_REGNUM) \
01004 ? 1 : NUM_REGS (MODE))
01005
01006
01007 #define HARD_REGNO_MODE_OK(REGNO, MODE) \
01008 arm_hard_regno_mode_ok ((REGNO), (MODE))
01009
01010
01011
01012
01013
01014 #define MODES_TIEABLE_P(MODE1, MODE2) \
01015 (GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2))
01016
01017
01018
01019
01020
01021
01022
01023 #define REG_ALLOC_ORDER \
01024 { \
01025 3, 2, 1, 0, 12, 14, 4, 5, \
01026 6, 7, 8, 10, 9, 11, 13, 15, \
01027 16, 17, 18, 19, 20, 21, 22, 23, \
01028 24, 25, 26 \
01029 }
01030
01031
01032
01033
01034 #define HARD_REGNO_RENAME_OK(SRC, DST) \
01035 (! IS_INTERRUPT (cfun->machine->func_type) || \
01036 regs_ever_live[DST])
01037
01038
01039
01040
01041
01042 enum reg_class
01043 {
01044 NO_REGS,
01045 FPU_REGS,
01046 LO_REGS,
01047 STACK_REG,
01048 BASE_REGS,
01049 HI_REGS,
01050 CC_REG,
01051 GENERAL_REGS,
01052 ALL_REGS,
01053 LIM_REG_CLASSES
01054 };
01055
01056 #define N_REG_CLASSES (int) LIM_REG_CLASSES
01057
01058
01059 #define REG_CLASS_NAMES \
01060 { \
01061 "NO_REGS", \
01062 "FPU_REGS", \
01063 "LO_REGS", \
01064 "STACK_REG", \
01065 "BASE_REGS", \
01066 "HI_REGS", \
01067 "CC_REG", \
01068 "GENERAL_REGS", \
01069 "ALL_REGS", \
01070 }
01071
01072
01073
01074
01075 #define REG_CLASS_CONTENTS \
01076 { \
01077 { 0x0000000 }, \
01078 { 0x0FF0000 }, \
01079 { 0x00000FF }, \
01080 { 0x0002000 }, \
01081 { 0x00020FF }, \
01082 { 0x000FF00 }, \
01083 { 0x1000000 }, \
01084 { 0x200FFFF }, \
01085 { 0x2FFFFFF } \
01086 }
01087
01088
01089
01090
01091
01092 #define REGNO_REG_CLASS(REGNO) arm_regno_class (REGNO)
01093
01094
01095 #define INDEX_REG_CLASS (TARGET_THUMB ? LO_REGS : GENERAL_REGS)
01096 #define BASE_REG_CLASS (TARGET_THUMB ? LO_REGS : GENERAL_REGS)
01097
01098
01099
01100
01101
01102
01103 #define MODE_BASE_REG_CLASS(MODE) \
01104 (TARGET_ARM ? GENERAL_REGS : \
01105 (((MODE) == SImode && !reload_completed) ? BASE_REGS : LO_REGS))
01106
01107
01108
01109
01110
01111 #define SMALL_REGISTER_CLASSES TARGET_THUMB
01112
01113
01114
01115
01116 #define REG_CLASS_FROM_LETTER(C) \
01117 ( (C) == 'f' ? FPU_REGS \
01118 : (C) == 'l' ? (TARGET_ARM ? GENERAL_REGS : LO_REGS) \
01119 : TARGET_ARM ? NO_REGS \
01120 : (C) == 'h' ? HI_REGS \
01121 : (C) == 'b' ? BASE_REGS \
01122 : (C) == 'k' ? STACK_REG \
01123 : (C) == 'c' ? CC_REG \
01124 : NO_REGS)
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136 #define CONST_OK_FOR_ARM_LETTER(VALUE, C) \
01137 ((C) == 'I' ? const_ok_for_arm (VALUE) : \
01138 (C) == 'J' ? ((VALUE) < 4096 && (VALUE) > -4096) : \
01139 (C) == 'K' ? (const_ok_for_arm (~(VALUE))) : \
01140 (C) == 'L' ? (const_ok_for_arm (-(VALUE))) : \
01141 (C) == 'M' ? (((VALUE >= 0 && VALUE <= 32)) \
01142 || (((VALUE) & ((VALUE) - 1)) == 0)) \
01143 : 0)
01144
01145 #define CONST_OK_FOR_THUMB_LETTER(VAL, C) \
01146 ((C) == 'I' ? (unsigned HOST_WIDE_INT) (VAL) < 256 : \
01147 (C) == 'J' ? (VAL) > -256 && (VAL) < 0 : \
01148 (C) == 'K' ? thumb_shiftable_const (VAL) : \
01149 (C) == 'L' ? (VAL) > -8 && (VAL) < 8 : \
01150 (C) == 'M' ? ((unsigned HOST_WIDE_INT) (VAL) < 1024 \
01151 && ((VAL) & 3) == 0) : \
01152 (C) == 'N' ? ((unsigned HOST_WIDE_INT) (VAL) < 32) : \
01153 (C) == 'O' ? ((VAL) >= -508 && (VAL) <= 508) \
01154 : 0)
01155
01156 #define CONST_OK_FOR_LETTER_P(VALUE, C) \
01157 (TARGET_ARM ? \
01158 CONST_OK_FOR_ARM_LETTER (VALUE, C) : CONST_OK_FOR_THUMB_LETTER (VALUE, C))
01159
01160
01161
01162 #define CONST_DOUBLE_OK_FOR_ARM_LETTER(X, C) \
01163 ((C) == 'G' ? const_double_rtx_ok_for_fpu (X) : \
01164 (C) == 'H' ? neg_const_double_rtx_ok_for_fpu (X) : 0)
01165
01166 #define CONST_DOUBLE_OK_FOR_LETTER_P(X, C) \
01167 (TARGET_ARM ? \
01168 CONST_DOUBLE_OK_FOR_ARM_LETTER (X, C) : 0)
01169
01170
01171
01172
01173
01174
01175
01176 #define EXTRA_CONSTRAINT_ARM(OP, C) \
01177 ((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG : \
01178 (C) == 'R' ? (GET_CODE (OP) == MEM \
01179 && GET_CODE (XEXP (OP, 0)) == SYMBOL_REF \
01180 && CONSTANT_POOL_ADDRESS_P (XEXP (OP, 0))) : \
01181 (C) == 'S' ? (optimize > 0 && CONSTANT_ADDRESS_P (OP)) \
01182 : 0)
01183
01184 #define EXTRA_CONSTRAINT_THUMB(X, C) \
01185 ((C) == 'Q' ? (GET_CODE (X) == MEM \
01186 && GET_CODE (XEXP (X, 0)) == LABEL_REF) : 0)
01187
01188 #define EXTRA_CONSTRAINT(X, C) \
01189 (TARGET_ARM ? \
01190 EXTRA_CONSTRAINT_ARM (X, C) : EXTRA_CONSTRAINT_THUMB (X, C))
01191
01192
01193
01194
01195
01196 #define PREFERRED_RELOAD_CLASS(X, CLASS) \
01197 (TARGET_ARM ? (CLASS) : \
01198 ((CLASS) == BASE_REGS ? (CLASS) : LO_REGS))
01199
01200
01201 #define THUMB_SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X) \
01202 ((CLASS) != LO_REGS && (CLASS) != BASE_REGS \
01203 ? ((true_regnum (X) == -1 ? LO_REGS \
01204 : (true_regnum (X) + HARD_REGNO_NREGS (0, MODE) > 8) ? LO_REGS \
01205 : NO_REGS)) \
01206 : NO_REGS)
01207
01208 #define THUMB_SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X) \
01209 ((CLASS) != LO_REGS \
01210 ? ((true_regnum (X) == -1 ? LO_REGS \
01211 : (true_regnum (X) + HARD_REGNO_NREGS (0, MODE) > 8) ? LO_REGS \
01212 : NO_REGS)) \
01213 : NO_REGS)
01214
01215
01216
01217
01218 #define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X) \
01219 (TARGET_ARM ? \
01220 (((MODE) == HImode && ! arm_arch4 && true_regnum (X) == -1) \
01221 ? GENERAL_REGS : NO_REGS) \
01222 : THUMB_SECONDARY_OUTPUT_RELOAD_CLASS (CLASS, MODE, X))
01223
01224
01225 #define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X) \
01226 (TARGET_ARM ? \
01227 (((MODE) == HImode && ! arm_arch4 && TARGET_MMU_TRAPS \
01228 && (GET_CODE (X) == MEM \
01229 || ((GET_CODE (X) == REG || GET_CODE (X) == SUBREG) \
01230 && true_regnum (X) == -1))) \
01231 ? GENERAL_REGS : NO_REGS) \
01232 : THUMB_SECONDARY_INPUT_RELOAD_CLASS (CLASS, MODE, X))
01233
01234
01235
01236
01237
01238
01239
01240
01241 #define ARM_LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, IND, WIN) \
01242 do \
01243 { \
01244 if (GET_CODE (X) == PLUS \
01245 && GET_CODE (XEXP (X, 0)) == REG \
01246 && REGNO (XEXP (X, 0)) < FIRST_PSEUDO_REGISTER \
01247 && REG_MODE_OK_FOR_BASE_P (XEXP (X, 0), MODE) \
01248 && GET_CODE (XEXP (X, 1)) == CONST_INT) \
01249 { \
01250 HOST_WIDE_INT val = INTVAL (XEXP (X, 1)); \
01251 HOST_WIDE_INT low, high; \
01252 \
01253 if (MODE == DImode || (TARGET_SOFT_FLOAT && MODE == DFmode)) \
01254 low = ((val & 0xf) ^ 0x8) - 0x8; \
01255 else if (MODE == SImode \
01256 || (MODE == SFmode && TARGET_SOFT_FLOAT) \
01257 || ((MODE == HImode || MODE == QImode) && ! arm_arch4)) \
01258 \
01259 low = val >= 0 ? (val & 0xfff) : -((-val) & 0xfff); \
01260 else if ((MODE == HImode || MODE == QImode) && arm_arch4) \
01261 \
01262 low = val >= 0 ? (val & 0xff) : -((-val) & 0xff); \
01263 else if (GET_MODE_CLASS (MODE) == MODE_FLOAT \
01264 && TARGET_HARD_FLOAT) \
01265 \
01266 low = val >= 0 ? (val & 0x3ff) : -((-val) & 0x3ff); \
01267 else \
01268 break; \
01269 \
01270 high = ((((val - low) & (unsigned HOST_WIDE_INT) 0xffffffff) \
01271 ^ (unsigned HOST_WIDE_INT) 0x80000000) \
01272 - (unsigned HOST_WIDE_INT) 0x80000000); \
01273 \
01274 if (low == 0 || high == 0 || (high + low != val)) \
01275 break; \
01276 \
01277
01278 \
01279 X = gen_rtx_PLUS (GET_MODE (X), \
01280 gen_rtx_PLUS (GET_MODE (X), XEXP (X, 0), \
01281 GEN_INT (high)), \
01282 GEN_INT (low)); \
01283 push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL, \
01284 MODE_BASE_REG_CLASS (MODE), GET_MODE (X), \
01285 VOIDmode, 0, 0, OPNUM, TYPE); \
01286 goto WIN; \
01287 } \
01288 } \
01289 while (0)
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299 #define THUMB_LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, IND_LEVELS, WIN) \
01300 { \
01301 if (GET_CODE (X) == PLUS \
01302 && GET_MODE_SIZE (MODE) < 4 \
01303 && GET_CODE (XEXP (X, 0)) == REG \
01304 && XEXP (X, 0) == stack_pointer_rtx \
01305 && GET_CODE (XEXP (X, 1)) == CONST_INT \
01306 && ! THUMB_LEGITIMATE_OFFSET (MODE, INTVAL (XEXP (X, 1)))) \
01307 { \
01308 rtx orig_X = X; \
01309 X = copy_rtx (X); \
01310 push_reload (orig_X, NULL_RTX, &X, NULL, \
01311 MODE_BASE_REG_CLASS (MODE), \
01312 Pmode, VOIDmode, 0, 0, OPNUM, TYPE); \
01313 goto WIN; \
01314 } \
01315 }
01316
01317 #define LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, IND_LEVELS, WIN) \
01318 if (TARGET_ARM) \
01319 ARM_LEGITIMIZE_RELOAD_ADDRESS (X, MODE, OPNUM, TYPE, IND_LEVELS, WIN); \
01320 else \
01321 THUMB_LEGITIMIZE_RELOAD_ADDRESS (X, MODE, OPNUM, TYPE, IND_LEVELS, WIN)
01322
01323
01324
01325
01326 #define CLASS_MAX_NREGS(CLASS, MODE) \
01327 ((CLASS) == FPU_REGS ? 1 : NUM_REGS (MODE))
01328
01329
01330 #define REGISTER_MOVE_COST(MODE, FROM, TO) \
01331 (TARGET_ARM ? \
01332 ((FROM) == FPU_REGS && (TO) != FPU_REGS ? 20 : \
01333 (FROM) != FPU_REGS && (TO) == FPU_REGS ? 20 : 2) \
01334 : \
01335 ((FROM) == HI_REGS || (TO) == HI_REGS) ? 4 : 2)
01336
01337
01338
01339
01340
01341 #define STACK_GROWS_DOWNWARD 1
01342
01343
01344
01345
01346
01347 #define FRAME_GROWS_DOWNWARD 1
01348
01349
01350
01351
01352
01353 #define STARTING_FRAME_OFFSET 0
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364 #define ACCUMULATE_OUTGOING_ARGS 1
01365
01366
01367 #define FIRST_PARM_OFFSET(FNDECL) (TARGET_ARM ? 4 : 0)
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378 #define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, SIZE) 0
01379
01380
01381
01382 #define LIBCALL_VALUE(MODE) \
01383 (TARGET_ARM && TARGET_HARD_FLOAT && GET_MODE_CLASS (MODE) == MODE_FLOAT \
01384 ? gen_rtx_REG (MODE, FIRST_ARM_FP_REGNUM) \
01385 : gen_rtx_REG (MODE, ARG_REGISTER (1)))
01386
01387
01388
01389
01390
01391 #define FUNCTION_VALUE(VALTYPE, FUNC) \
01392 LIBCALL_VALUE (TYPE_MODE (VALTYPE))
01393
01394
01395
01396 #define FUNCTION_VALUE_REGNO_P(REGNO) \
01397 ((REGNO) == ARG_REGISTER (1) \
01398 || (TARGET_ARM && ((REGNO) == FIRST_ARM_FP_REGNUM) && TARGET_HARD_FLOAT))
01399
01400
01401
01402
01403 #define RETURN_IN_MEMORY(TYPE) arm_return_in_memory (TYPE)
01404
01405
01406
01407
01408 #define DEFAULT_PCC_STRUCT_RETURN 0
01409
01410
01411 #define CALL_NORMAL 0x00000000
01412 #define CALL_LONG 0x00000001
01413 #define CALL_SHORT 0x00000002
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426 #define ARM_FT_UNKNOWN 0
01427 #define ARM_FT_NORMAL 1
01428 #define ARM_FT_INTERWORKED 2
01429 #define ARM_FT_EXCEPTION_HANDLER 3
01430 #define ARM_FT_ISR 4
01431 #define ARM_FT_FIQ 5
01432 #define ARM_FT_EXCEPTION 6
01433
01434 #define ARM_FT_TYPE_MASK ((1 << 3) - 1)
01435
01436
01437
01438 #define ARM_FT_INTERRUPT (1 << 2)
01439 #define ARM_FT_NAKED (1 << 3)
01440 #define ARM_FT_VOLATILE (1 << 4)
01441 #define ARM_FT_NESTED (1 << 5)
01442
01443
01444 #define ARM_FUNC_TYPE(t) (t & ARM_FT_TYPE_MASK)
01445 #define IS_INTERRUPT(t) (t & ARM_FT_INTERRUPT)
01446 #define IS_VOLATILE(t) (t & ARM_FT_VOLATILE)
01447 #define IS_NAKED(t) (t & ARM_FT_NAKED)
01448 #define IS_NESTED(t) (t & ARM_FT_NESTED)
01449
01450
01451
01452 typedef struct machine_function
01453 {
01454
01455 struct rtx_def *eh_epilogue_sp_ofs;
01456
01457 int far_jump_used;
01458
01459 int arg_pointer_live;
01460
01461 int lr_save_eliminated;
01462
01463 unsigned long func_type;
01464
01465 int uses_anonymous_args;
01466 }
01467 machine_function;
01468
01469
01470
01471
01472 typedef struct
01473 {
01474
01475 int nregs;
01476
01477 int call_cookie;
01478 } CUMULATIVE_ARGS;
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498 #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
01499 arm_function_arg (&(CUM), (MODE), (TYPE), (NAMED))
01500
01501
01502
01503
01504 #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
01505 ( NUM_ARG_REGS > (CUM).nregs \
01506 && (NUM_ARG_REGS < ((CUM).nregs + NUM_REGS2 (MODE, TYPE))) \
01507 ? NUM_ARG_REGS - (CUM).nregs : 0)
01508
01509
01510
01511
01512
01513 #define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT) \
01514 arm_init_cumulative_args (&(CUM), (FNTYPE), (LIBNAME), (INDIRECT))
01515
01516
01517
01518
01519 #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
01520 (CUM).nregs += NUM_REGS2 (MODE, TYPE)
01521
01522
01523
01524 #define FUNCTION_ARG_REGNO_P(REGNO) (IN_RANGE ((REGNO), 0, 3))
01525
01526
01527
01528
01529
01530
01531 #define FUNCTION_OK_FOR_SIBCALL(DECL) arm_function_ok_for_sibcall ((DECL))
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546 #define SETUP_INCOMING_VARARGS(CUM, MODE, TYPE, PRETEND_SIZE, NO_RTL) \
01547 { \
01548 cfun->machine->uses_anonymous_args = 1; \
01549 if ((CUM).nregs < NUM_ARG_REGS) \
01550 (PRETEND_SIZE) = (NUM_ARG_REGS - (CUM).nregs) * UNITS_PER_WORD; \
01551 }
01552
01553
01554
01555
01556 #ifndef ARM_MCOUNT_NAME
01557 #define ARM_MCOUNT_NAME "*mcount"
01558 #endif
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576 #ifndef ARM_FUNCTION_PROFILER
01577 #define ARM_FUNCTION_PROFILER(STREAM, LABELNO) \
01578 { \
01579 char temp[20]; \
01580 rtx sym; \
01581 \
01582 asm_fprintf (STREAM, "\tmov\t%r, %r\n\tbl\t", \
01583 IP_REGNUM, LR_REGNUM); \
01584 assemble_name (STREAM, ARM_MCOUNT_NAME); \
01585 fputc ('\n', STREAM); \
01586 ASM_GENERATE_INTERNAL_LABEL (temp, "LP", LABELNO); \
01587 sym = gen_rtx (SYMBOL_REF, Pmode, temp); \
01588 assemble_aligned_integer (UNITS_PER_WORD, sym); \
01589 }
01590 #endif
01591
01592 #ifndef THUMB_FUNCTION_PROFILER
01593 #define THUMB_FUNCTION_PROFILER(STREAM, LABELNO) \
01594 { \
01595 fprintf (STREAM, "\tmov\tip, lr\n"); \
01596 fprintf (STREAM, "\tbl\tmcount\n"); \
01597 fprintf (STREAM, "\t.word\tLP%d\n", LABELNO); \
01598 }
01599 #endif
01600
01601 #define FUNCTION_PROFILER(STREAM, LABELNO) \
01602 if (TARGET_ARM) \
01603 ARM_FUNCTION_PROFILER (STREAM, LABELNO) \
01604 else \
01605 THUMB_FUNCTION_PROFILER (STREAM, LABELNO)
01606
01607
01608
01609
01610
01611
01612
01613
01614 #define EXIT_IGNORE_STACK 1
01615
01616 #define EPILOGUE_USES(REGNO) (reload_completed && (REGNO) == LR_REGNUM)
01617
01618
01619
01620 #define USE_RETURN_INSN(ISCOND) \
01621 (TARGET_ARM ? use_return_insn (ISCOND) : 0)
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637 #define ELIMINABLE_REGS \
01638 {{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM },\
01639 { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM },\
01640 { ARG_POINTER_REGNUM, ARM_HARD_FRAME_POINTER_REGNUM },\
01641 { ARG_POINTER_REGNUM, THUMB_HARD_FRAME_POINTER_REGNUM },\
01642 { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM },\
01643 { FRAME_POINTER_REGNUM, ARM_HARD_FRAME_POINTER_REGNUM },\
01644 { FRAME_POINTER_REGNUM, THUMB_HARD_FRAME_POINTER_REGNUM }}
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654 #define CAN_ELIMINATE(FROM, TO) \
01655 (((TO) == FRAME_POINTER_REGNUM && (FROM) == ARG_POINTER_REGNUM) ? 0 : \
01656 ((TO) == STACK_POINTER_REGNUM && frame_pointer_needed) ? 0 : \
01657 ((TO) == ARM_HARD_FRAME_POINTER_REGNUM && TARGET_THUMB) ? 0 : \
01658 ((TO) == THUMB_HARD_FRAME_POINTER_REGNUM && TARGET_ARM) ? 0 : \
01659 1)
01660
01661
01662
01663 #define ARM_INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
01664 do \
01665 { \
01666 (OFFSET) = arm_compute_initial_elimination_offset (FROM, TO); \
01667 } \
01668 while (0)
01669
01670
01671 #define THUMB_INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
01672 { \
01673 (OFFSET) = 0; \
01674 if ((FROM) == ARG_POINTER_REGNUM) \
01675 { \
01676 int count_regs = 0; \
01677 int regno; \
01678 for (regno = 8; regno < 13; regno ++) \
01679 if (regs_ever_live[regno] && ! call_used_regs[regno]) \
01680 count_regs ++; \
01681 if (count_regs) \
01682 (OFFSET) += 4 * count_regs; \
01683 count_regs = 0; \
01684 for (regno = 0; regno <= LAST_LO_REGNUM; regno ++) \
01685 if (regs_ever_live[regno] && ! call_used_regs[regno]) \
01686 count_regs ++; \
01687 if (count_regs || ! leaf_function_p () || thumb_far_jump_used_p (0))\
01688 (OFFSET) += 4 * (count_regs + 1); \
01689 if (TARGET_BACKTRACE) \
01690 { \
01691 if ((count_regs & 0xFF) == 0 && (regs_ever_live[3] != 0)) \
01692 (OFFSET) += 20; \
01693 else \
01694 (OFFSET) += 16; \
01695 } \
01696 } \
01697 if ((TO) == STACK_POINTER_REGNUM) \
01698 { \
01699 (OFFSET) += current_function_outgoing_args_size; \
01700 (OFFSET) += ROUND_UP (get_frame_size ()); \
01701 } \
01702 }
01703
01704 #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
01705 if (TARGET_ARM) \
01706 ARM_INITIAL_ELIMINATION_OFFSET (FROM, TO, OFFSET); \
01707 else \
01708 THUMB_INITIAL_ELIMINATION_OFFSET (FROM, TO, OFFSET)
01709
01710
01711 #define DEBUGGER_ARG_OFFSET(value, addr) value ? value : arm_debugger_arg_offset (value, addr)
01712
01713
01714
01715 #define INIT_EXPANDERS arm_init_expanders ()
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727 #define ARM_TRAMPOLINE_TEMPLATE(FILE) \
01728 { \
01729 asm_fprintf (FILE, "\tldr\t%r, [%r, #0]\n", \
01730 STATIC_CHAIN_REGNUM, PC_REGNUM); \
01731 asm_fprintf (FILE, "\tldr\t%r, [%r, #0]\n", \
01732 PC_REGNUM, PC_REGNUM); \
01733 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx); \
01734 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx); \
01735 }
01736
01737
01738
01739
01740
01741
01742
01743
01744 #define THUMB_TRAMPOLINE_TEMPLATE(FILE) \
01745 { \
01746 fprintf (FILE, "\t.code 32\n"); \
01747 fprintf (FILE, ".Ltrampoline_start:\n"); \
01748 asm_fprintf (FILE, "\tldr\t%r, [%r, #8]\n", \
01749 STATIC_CHAIN_REGNUM, PC_REGNUM); \
01750 asm_fprintf (FILE, "\tldr\t%r, [%r, #8]\n", \
01751 IP_REGNUM, PC_REGNUM); \
01752 asm_fprintf (FILE, "\torr\t%r, %r, #1\n", \
01753 IP_REGNUM, IP_REGNUM); \
01754 asm_fprintf (FILE, "\tbx\t%r\n", IP_REGNUM); \
01755 fprintf (FILE, "\t.word\t0\n"); \
01756 fprintf (FILE, "\t.word\t0\n"); \
01757 fprintf (FILE, "\t.code 16\n"); \
01758 }
01759
01760 #define TRAMPOLINE_TEMPLATE(FILE) \
01761 if (TARGET_ARM) \
01762 ARM_TRAMPOLINE_TEMPLATE (FILE) \
01763 else \
01764 THUMB_TRAMPOLINE_TEMPLATE (FILE)
01765
01766
01767 #define TRAMPOLINE_SIZE (TARGET_ARM ? 16 : 24)
01768
01769
01770 #define TRAMPOLINE_ALIGNMENT 32
01771
01772
01773
01774
01775 #define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
01776 { \
01777 emit_move_insn \
01778 (gen_rtx_MEM (SImode, plus_constant (TRAMP, TARGET_ARM ? 8 : 16)), CXT); \
01779 emit_move_insn \
01780 (gen_rtx_MEM (SImode, plus_constant (TRAMP, TARGET_ARM ? 12 : 20)), FNADDR); \
01781 }
01782
01783
01784
01785 #define HAVE_POST_INCREMENT 1
01786 #define HAVE_PRE_INCREMENT TARGET_ARM
01787 #define HAVE_POST_DECREMENT TARGET_ARM
01788 #define HAVE_PRE_DECREMENT TARGET_ARM
01789
01790
01791
01792
01793
01794
01795
01796
01797 #define TEST_REGNO(R, TEST, VALUE) \
01798 ((R TEST VALUE) || ((unsigned) reg_renumber[R] TEST VALUE))
01799
01800
01801 #define ARM_REGNO_OK_FOR_BASE_P(REGNO) \
01802 (TEST_REGNO (REGNO, <, PC_REGNUM) \
01803 || TEST_REGNO (REGNO, ==, FRAME_POINTER_REGNUM) \
01804 || TEST_REGNO (REGNO, ==, ARG_POINTER_REGNUM))
01805
01806 #define THUMB_REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) \
01807 (TEST_REGNO (REGNO, <=, LAST_LO_REGNUM) \
01808 || (GET_MODE_SIZE (MODE) >= 4 \
01809 && TEST_REGNO (REGNO, ==, STACK_POINTER_REGNUM)))
01810
01811 #define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) \
01812 (TARGET_THUMB \
01813 ? THUMB_REGNO_MODE_OK_FOR_BASE_P (REGNO, MODE) \
01814 : ARM_REGNO_OK_FOR_BASE_P (REGNO))
01815
01816
01817
01818 #define REGNO_OK_FOR_INDEX_P(REGNO) \
01819 REGNO_MODE_OK_FOR_BASE_P (REGNO, QImode)
01820
01821
01822
01823 #define MAX_REGS_PER_ADDRESS 2
01824
01825
01826
01827
01828 #ifdef AOF_ASSEMBLER
01829
01830 #define CONSTANT_ADDRESS_P(X) \
01831 (GET_CODE (X) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (X))
01832
01833 #else
01834
01835 #define CONSTANT_ADDRESS_P(X) \
01836 (GET_CODE (X) == SYMBOL_REF \
01837 && (CONSTANT_POOL_ADDRESS_P (X) \
01838 || (TARGET_ARM && optimize > 0 && SYMBOL_REF_FLAG (X))))
01839
01840 #endif
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850 #define ARM_LEGITIMATE_CONSTANT_P(X) (flag_pic || ! label_mentioned_p (X))
01851
01852 #define THUMB_LEGITIMATE_CONSTANT_P(X) \
01853 ( GET_CODE (X) == CONST_INT \
01854 || GET_CODE (X) == CONST_DOUBLE \
01855 || CONSTANT_ADDRESS_P (X) \
01856 || flag_pic)
01857
01858 #define LEGITIMATE_CONSTANT_P(X) \
01859 (TARGET_ARM ? ARM_LEGITIMATE_CONSTANT_P (X) : THUMB_LEGITIMATE_CONSTANT_P (X))
01860
01861
01862
01863
01864 #define SHORT_CALL_FLAG_CHAR '^'
01865 #define LONG_CALL_FLAG_CHAR '#'
01866
01867 #define ENCODED_SHORT_CALL_ATTR_P(SYMBOL_NAME) \
01868 (*(SYMBOL_NAME) == SHORT_CALL_FLAG_CHAR)
01869
01870 #define ENCODED_LONG_CALL_ATTR_P(SYMBOL_NAME) \
01871 (*(SYMBOL_NAME) == LONG_CALL_FLAG_CHAR)
01872
01873 #ifndef SUBTARGET_NAME_ENCODING_LENGTHS
01874 #define SUBTARGET_NAME_ENCODING_LENGTHS
01875 #endif
01876
01877
01878
01879
01880
01881 #define ARM_NAME_ENCODING_LENGTHS \
01882 case SHORT_CALL_FLAG_CHAR: return 1; \
01883 case LONG_CALL_FLAG_CHAR: return 1; \
01884 case '*': return 1; \
01885 SUBTARGET_NAME_ENCODING_LENGTHS
01886
01887
01888
01889 #undef STRIP_NAME_ENCODING
01890 #define STRIP_NAME_ENCODING(VAR, SYMBOL_NAME) \
01891 (VAR) = arm_strip_name_encoding (SYMBOL_NAME)
01892
01893
01894
01895 #undef ASM_OUTPUT_LABELREF
01896 #define ASM_OUTPUT_LABELREF(FILE, NAME) \
01897 asm_fprintf (FILE, "%U%s", arm_strip_name_encoding (NAME))
01898
01899
01900
01901
01902
01903 #define ARM_ENCODE_CALL_TYPE(decl) \
01904 if (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd') \
01905 { \
01906 if (TREE_CODE (decl) == FUNCTION_DECL && DECL_WEAK (decl)) \
01907 arm_encode_call_attribute (decl, LONG_CALL_FLAG_CHAR); \
01908 else if (! TREE_PUBLIC (decl)) \
01909 arm_encode_call_attribute (decl, SHORT_CALL_FLAG_CHAR); \
01910 }
01911
01912
01913
01914
01915
01916
01917
01918
01919 #ifndef AOF_ASSEMBLER
01920 #define ENCODE_SECTION_INFO(decl) \
01921 { \
01922 if (optimize > 0 && TREE_CONSTANT (decl) \
01923 && (!flag_writable_strings || TREE_CODE (decl) != STRING_CST)) \
01924 { \
01925 rtx rtl = (TREE_CODE_CLASS (TREE_CODE (decl)) != 'd' \
01926 ? TREE_CST_RTL (decl) : DECL_RTL (decl)); \
01927 SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1; \
01928 } \
01929 ARM_ENCODE_CALL_TYPE (decl) \
01930 }
01931 #else
01932 #define ENCODE_SECTION_INFO(decl) \
01933 { \
01934 ARM_ENCODE_CALL_TYPE (decl) \
01935 }
01936 #endif
01937
01938 #define ARM_DECLARE_FUNCTION_SIZE(STREAM, NAME, DECL) \
01939 arm_encode_call_attribute (DECL, SHORT_CALL_FLAG_CHAR)
01940
01941
01942
01943
01944
01945
01946
01947 #ifndef REG_OK_STRICT
01948
01949 #define ARM_REG_OK_FOR_BASE_P(X) \
01950 (REGNO (X) <= LAST_ARM_REGNUM \
01951 || REGNO (X) >= FIRST_PSEUDO_REGISTER \
01952 || REGNO (X) == FRAME_POINTER_REGNUM \
01953 || REGNO (X) == ARG_POINTER_REGNUM)
01954
01955 #define THUMB_REG_MODE_OK_FOR_BASE_P(X, MODE) \
01956 (REGNO (X) <= LAST_LO_REGNUM \
01957 || REGNO (X) >= FIRST_PSEUDO_REGISTER \
01958 || (GET_MODE_SIZE (MODE) >= 4 \
01959 && (REGNO (X) == STACK_POINTER_REGNUM \
01960 || (X) == hard_frame_pointer_rtx \
01961 || (X) == arg_pointer_rtx)))
01962
01963 #else
01964
01965 #define ARM_REG_OK_FOR_BASE_P(X) \
01966 ARM_REGNO_OK_FOR_BASE_P (REGNO (X))
01967
01968 #define THUMB_REG_MODE_OK_FOR_BASE_P(X, MODE) \
01969 THUMB_REGNO_MODE_OK_FOR_BASE_P (REGNO (X), MODE)
01970
01971 #endif
01972
01973
01974
01975 #define REG_MODE_OK_FOR_BASE_P(X, MODE) \
01976 (TARGET_THUMB \
01977 ? THUMB_REG_MODE_OK_FOR_BASE_P (X, MODE) \
01978 : ARM_REG_OK_FOR_BASE_P (X))
01979
01980 #define ARM_REG_OK_FOR_INDEX_P(X) ARM_REG_OK_FOR_BASE_P (X)
01981
01982
01983
01984 #define THUMB_REG_OK_FOR_INDEX_P(X) THUMB_REG_MODE_OK_FOR_BASE_P (X, QImode)
01985
01986
01987
01988
01989 #define REG_OK_FOR_INDEX_P(X) \
01990 (TARGET_THUMB \
01991 ? THUMB_REG_OK_FOR_INDEX_P (X) \
01992 : ARM_REG_OK_FOR_INDEX_P (X))
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003 #define ARM_BASE_REGISTER_RTX_P(X) \
02004 (GET_CODE (X) == REG && ARM_REG_OK_FOR_BASE_P (X))
02005
02006 #define ARM_INDEX_REGISTER_RTX_P(X) \
02007 (GET_CODE (X) == REG && ARM_REG_OK_FOR_INDEX_P (X))
02008
02009
02010
02011
02012 #define ARM_GO_IF_LEGITIMATE_INDEX(MODE, BASE_REGNO, INDEX, LABEL) \
02013 do \
02014 { \
02015 HOST_WIDE_INT range; \
02016 enum rtx_code code = GET_CODE (INDEX); \
02017 \
02018 if (TARGET_HARD_FLOAT && GET_MODE_CLASS (MODE) == MODE_FLOAT) \
02019 { \
02020 if (code == CONST_INT && INTVAL (INDEX) < 1024 \
02021 && INTVAL (INDEX) > -1024 \
02022 && (INTVAL (INDEX) & 3) == 0) \
02023 goto LABEL; \
02024 } \
02025 else \
02026 { \
02027 if (ARM_INDEX_REGISTER_RTX_P (INDEX) \
02028 && GET_MODE_SIZE (MODE) <= 4) \
02029 goto LABEL; \
02030 if (GET_MODE_SIZE (MODE) <= 4 && code == MULT \
02031 && (! arm_arch4 || (MODE) != HImode)) \
02032 { \
02033 rtx xiop0 = XEXP (INDEX, 0); \
02034 rtx xiop1 = XEXP (INDEX, 1); \
02035 if (ARM_INDEX_REGISTER_RTX_P (xiop0) \
02036 && power_of_two_operand (xiop1, SImode)) \
02037 goto LABEL; \
02038 if (ARM_INDEX_REGISTER_RTX_P (xiop1) \
02039 && power_of_two_operand (xiop0, SImode)) \
02040 goto LABEL; \
02041 } \
02042 if (GET_MODE_SIZE (MODE) <= 4 \
02043 && (code == LSHIFTRT || code == ASHIFTRT \
02044 || code == ASHIFT || code == ROTATERT) \
02045 && (! arm_arch4 || (MODE) != HImode)) \
02046 { \
02047 rtx op = XEXP (INDEX, 1); \
02048 if (ARM_INDEX_REGISTER_RTX_P (XEXP (INDEX, 0)) \
02049 && GET_CODE (op) == CONST_INT && INTVAL (op) > 0 \
02050 && INTVAL (op) <= 31) \
02051 goto LABEL; \
02052 } \
02053
02054 \
02055 range = ((MODE) == HImode || (MODE) == QImode) \
02056 ? (arm_arch4 ? 256 : 4095) : 4096; \
02057 if (code == CONST_INT && INTVAL (INDEX) < range \
02058 && INTVAL (INDEX) > -range) \
02059 goto LABEL; \
02060 } \
02061 } \
02062 while (0)
02063
02064
02065
02066
02067
02068
02069
02070
02071 #define ARM_GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \
02072 { \
02073 if (ARM_BASE_REGISTER_RTX_P (X)) \
02074 goto LABEL; \
02075 else if ((GET_CODE (X) == POST_INC || GET_CODE (X) == PRE_DEC) \
02076 && GET_CODE (XEXP (X, 0)) == REG \
02077 && ARM_REG_OK_FOR_BASE_P (XEXP (X, 0))) \
02078 goto LABEL; \
02079 else if (GET_MODE_SIZE (MODE) >= 4 && reload_completed \
02080 && (GET_CODE (X) == LABEL_REF \
02081 || (GET_CODE (X) == CONST \
02082 && GET_CODE (XEXP ((X), 0)) == PLUS \
02083 && GET_CODE (XEXP (XEXP ((X), 0), 0)) == LABEL_REF \
02084 && GET_CODE (XEXP (XEXP ((X), 0), 1)) == CONST_INT)))\
02085 goto LABEL; \
02086 else if ((MODE) == TImode) \
02087 ; \
02088 else if ((MODE) == DImode || (TARGET_SOFT_FLOAT && (MODE) == DFmode)) \
02089 { \
02090 if (GET_CODE (X) == PLUS && ARM_BASE_REGISTER_RTX_P (XEXP (X, 0)) \
02091 && GET_CODE (XEXP (X, 1)) == CONST_INT) \
02092 { \
02093 HOST_WIDE_INT val = INTVAL (XEXP (X, 1)); \
02094 if (val == 4 || val == -4 || val == -8) \
02095 goto LABEL; \
02096 } \
02097 } \
02098 else if (GET_CODE (X) == PLUS) \
02099 { \
02100 rtx xop0 = XEXP (X, 0); \
02101 rtx xop1 = XEXP (X, 1); \
02102 \
02103 if (ARM_BASE_REGISTER_RTX_P (xop0)) \
02104 ARM_GO_IF_LEGITIMATE_INDEX (MODE, REGNO (xop0), xop1, LABEL); \
02105 else if (ARM_BASE_REGISTER_RTX_P (xop1)) \
02106 ARM_GO_IF_LEGITIMATE_INDEX (MODE, REGNO (xop1), xop0, LABEL); \
02107 } \
02108 \
02109
02110
02111
02112
02113
02114
02115
02116 \
02117 else if (GET_MODE_CLASS (MODE) != MODE_FLOAT \
02118 && GET_CODE (X) == SYMBOL_REF \
02119 && CONSTANT_POOL_ADDRESS_P (X) \
02120 && ! (flag_pic \
02121 && symbol_mentioned_p (get_pool_constant (X)))) \
02122 goto LABEL; \
02123 else if ((GET_CODE (X) == PRE_INC || GET_CODE (X) == POST_DEC) \
02124 && (GET_MODE_SIZE (MODE) <= 4) \
02125 && GET_CODE (XEXP (X, 0)) == REG \
02126 && ARM_REG_OK_FOR_BASE_P (XEXP (X, 0))) \
02127 goto LABEL; \
02128 }
02129
02130
02131 #define THUMB_LEGITIMATE_OFFSET(MODE, VAL) \
02132 (GET_MODE_SIZE (MODE) == 1 ? ((unsigned HOST_WIDE_INT) (VAL) < 32) \
02133 : GET_MODE_SIZE (MODE) == 2 ? ((unsigned HOST_WIDE_INT) (VAL) < 64 \
02134 && ((VAL) & 1) == 0) \
02135 : ((VAL) >= 0 && ((VAL) + GET_MODE_SIZE (MODE)) <= 128 \
02136 && ((VAL) & 3) == 0))
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150
02151
02152
02153 #define THUMB_GO_IF_LEGITIMATE_ADDRESS(MODE, X, WIN) \
02154 { \
02155 \
02156 if (GET_MODE_SIZE (MODE) < 4 \
02157 && ! (reload_in_progress || reload_completed) \
02158 && ( reg_mentioned_p (frame_pointer_rtx, X) \
02159 || reg_mentioned_p (arg_pointer_rtx, X) \
02160 || reg_mentioned_p (virtual_incoming_args_rtx, X) \
02161 || reg_mentioned_p (virtual_outgoing_args_rtx, X) \
02162 || reg_mentioned_p (virtual_stack_dynamic_rtx, X) \
02163 || reg_mentioned_p (virtual_stack_vars_rtx, X))) \
02164 ; \
02165 \
02166 else if (GET_CODE (X) == REG \
02167 && THUMB_REG_MODE_OK_FOR_BASE_P (X, MODE)) \
02168 goto WIN; \
02169 \
02170 else if (GET_MODE_SIZE (MODE) >= 4 && CONSTANT_P (X) \
02171 && CONSTANT_POOL_ADDRESS_P (X) && ! flag_pic) \
02172 goto WIN; \
02173 \
02174 else if (GET_MODE_SIZE (MODE) >= 4 && reload_completed \
02175 && (GET_CODE (X) == LABEL_REF \
02176 || (GET_CODE (X) == CONST \
02177 && GET_CODE (XEXP (X, 0)) == PLUS \
02178 && GET_CODE (XEXP (XEXP (X, 0), 0)) == LABEL_REF \
02179 && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT))) \
02180 goto WIN; \
02181 \
02182 else if (GET_CODE (X) == POST_INC && GET_MODE_SIZE (MODE) >= 4 \
02183 && GET_CODE (XEXP (X, 0)) == REG \
02184 && THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 0))) \
02185 goto WIN; \
02186 else if (GET_CODE (X) == PLUS) \
02187 { \
02188 \
02189
02190
02191 \
02192 if (GET_MODE_SIZE (MODE) <= 4 \
02193 && GET_CODE (XEXP (X, 0)) == REG \
02194 && GET_CODE (XEXP (X, 1)) == REG \
02195 && XEXP (X, 0) != frame_pointer_rtx \
02196 && XEXP (X, 1) != frame_pointer_rtx \
02197 && XEXP (X, 0) != virtual_stack_vars_rtx \
02198 && XEXP (X, 1) != virtual_stack_vars_rtx \
02199 && THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 0)) \
02200 && THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 1))) \
02201 goto WIN; \
02202 \
02203 else if (GET_CODE (XEXP (X, 0)) == REG \
02204 && (THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 0)) \
02205 || XEXP (X, 0) == arg_pointer_rtx) \
02206 && GET_CODE (XEXP (X, 1)) == CONST_INT \
02207 && THUMB_LEGITIMATE_OFFSET (MODE, INTVAL (XEXP (X, 1)))) \
02208 goto WIN; \
02209
02210 \
02211
02212 \
02213 else if (GET_CODE (XEXP (X, 0)) == REG \
02214 && REGNO (XEXP (X, 0)) == STACK_POINTER_REGNUM \
02215 && GET_MODE_SIZE (MODE) >= 4 \
02216 && GET_CODE (XEXP (X, 1)) == CONST_INT \
02217 && ((unsigned HOST_WIDE_INT) INTVAL (XEXP (X, 1)) \
02218 + GET_MODE_SIZE (MODE)) <= 1024 \
02219 && (INTVAL (XEXP (X, 1)) & 3) == 0) \
02220 goto WIN; \
02221 else if (GET_CODE (XEXP (X, 0)) == REG \
02222 && REGNO (XEXP (X, 0)) == FRAME_POINTER_REGNUM \
02223 && GET_MODE_SIZE (MODE) >= 4 \
02224 && GET_CODE (XEXP (X, 1)) == CONST_INT \
02225 && (INTVAL (XEXP (X, 1)) & 3) == 0) \
02226 goto WIN; \
02227 } \
02228 else if (GET_MODE_CLASS (MODE) != MODE_FLOAT \
02229 && GET_CODE (X) == SYMBOL_REF \
02230 && CONSTANT_POOL_ADDRESS_P (X) \
02231 && ! (flag_pic \
02232 && symbol_mentioned_p (get_pool_constant (X)))) \
02233 goto WIN; \
02234 }
02235
02236
02237 #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, WIN) \
02238 if (TARGET_ARM) \
02239 ARM_GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN) \
02240 else \
02241 THUMB_GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN)
02242
02243
02244
02245
02246
02247
02248
02249
02250
02251
02252
02253
02254
02255
02256
02257
02258
02259
02260 #define ARM_LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
02261 { \
02262 if (GET_CODE (X) == PLUS) \
02263 { \
02264 rtx xop0 = XEXP (X, 0); \
02265 rtx xop1 = XEXP (X, 1); \
02266 \
02267 if (CONSTANT_P (xop0) && ! symbol_mentioned_p (xop0)) \
02268 xop0 = force_reg (SImode, xop0); \
02269 if (CONSTANT_P (xop1) && ! symbol_mentioned_p (xop1)) \
02270 xop1 = force_reg (SImode, xop1); \
02271 if (ARM_BASE_REGISTER_RTX_P (xop0) \
02272 && GET_CODE (xop1) == CONST_INT) \
02273 { \
02274 HOST_WIDE_INT n, low_n; \
02275 rtx base_reg, val; \
02276 n = INTVAL (xop1); \
02277 \
02278 if (MODE == DImode || (TARGET_SOFT_FLOAT && MODE == DFmode)) \
02279 { \
02280 low_n = n & 0x0f; \
02281 n &= ~0x0f; \
02282 if (low_n > 4) \
02283 { \
02284 n += 16; \
02285 low_n -= 16; \
02286 } \
02287 } \
02288 else \
02289 { \
02290 low_n = ((MODE) == TImode ? 0 \
02291 : n >= 0 ? (n & 0xfff) : -((-n) & 0xfff)); \
02292 n -= low_n; \
02293 } \
02294 base_reg = gen_reg_rtx (SImode); \
02295 val = force_operand (gen_rtx_PLUS (SImode, xop0, \
02296 GEN_INT (n)), NULL_RTX); \
02297 emit_move_insn (base_reg, val); \
02298 (X) = (low_n == 0 ? base_reg \
02299 : gen_rtx_PLUS (SImode, base_reg, GEN_INT (low_n))); \
02300 } \
02301 else if (xop0 != XEXP (X, 0) || xop1 != XEXP (x, 1)) \
02302 (X) = gen_rtx_PLUS (SImode, xop0, xop1); \
02303 } \
02304 else if (GET_CODE (X) == MINUS) \
02305 { \
02306 rtx xop0 = XEXP (X, 0); \
02307 rtx xop1 = XEXP (X, 1); \
02308 \
02309 if (CONSTANT_P (xop0)) \
02310 xop0 = force_reg (SImode, xop0); \
02311 if (CONSTANT_P (xop1) && ! symbol_mentioned_p (xop1)) \
02312 xop1 = force_reg (SImode, xop1); \
02313 if (xop0 != XEXP (X, 0) || xop1 != XEXP (X, 1)) \
02314 (X) = gen_rtx_MINUS (SImode, xop0, xop1); \
02315 } \
02316 if (flag_pic) \
02317 (X) = legitimize_pic_address (OLDX, MODE, NULL_RTX); \
02318 if (memory_address_p (MODE, X)) \
02319 goto WIN; \
02320 }
02321
02322 #define THUMB_LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
02323 if (flag_pic) \
02324 (X) = legitimize_pic_address (OLDX, MODE, NULL_RTX);
02325
02326 #define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
02327 if (TARGET_ARM) \
02328 ARM_LEGITIMIZE_ADDRESS (X, OLDX, MODE, WIN) \
02329 else \
02330 THUMB_LEGITIMIZE_ADDRESS (X, OLDX, MODE, WIN)
02331
02332
02333
02334 #define ARM_GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) \
02335 { \
02336 if ( GET_CODE (ADDR) == PRE_DEC || GET_CODE (ADDR) == POST_DEC \
02337 || GET_CODE (ADDR) == PRE_INC || GET_CODE (ADDR) == POST_INC) \
02338 goto LABEL; \
02339 }
02340
02341
02342 #define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) \
02343 if (TARGET_ARM) \
02344 ARM_GO_IF_MODE_DEPENDENT_ADDRESS (ADDR, LABEL)
02345
02346
02347
02348
02349 #define CASE_VECTOR_MODE Pmode
02350
02351
02352
02353
02354
02355
02356
02357
02358
02359 #ifndef DEFAULT_SIGNED_CHAR
02360 #define DEFAULT_SIGNED_CHAR 0
02361 #endif
02362
02363
02364 #define NO_RECURSIVE_FUNCTION_CSE 1
02365
02366
02367
02368 #define MOVE_MAX 4
02369
02370 #undef MOVE_RATIO
02371 #define MOVE_RATIO (arm_is_xscale ? 4 : 2)
02372
02373
02374
02375 #define WORD_REGISTER_OPERATIONS
02376
02377
02378
02379
02380
02381 #define LOAD_EXTEND_OP(MODE) \
02382 (TARGET_THUMB ? ZERO_EXTEND : \
02383 ((arm_arch4 || (MODE) == QImode) ? ZERO_EXTEND \
02384 : ((BYTES_BIG_ENDIAN && (MODE) == HImode) ? SIGN_EXTEND : NIL)))
02385
02386
02387 #define SLOW_BYTE_ACCESS 0
02388
02389 #define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) 1
02390
02391
02392
02393
02394
02395
02396
02397
02398
02399
02400
02401
02402
02403 #define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
02404
02405
02406 #define NO_FUNCTION_CSE 1
02407
02408
02409 #define PROMOTE_PROTOTYPES 1
02410
02411
02412 #define Pmode SImode
02413 #define FUNCTION_MODE Pmode
02414
02415 #define ARM_FRAME_RTX(X) \
02416 ( (X) == frame_pointer_rtx || (X) == stack_pointer_rtx \
02417 || (X) == arg_pointer_rtx)
02418
02419 #define DEFAULT_RTX_COSTS(X, CODE, OUTER_CODE) \
02420 return arm_rtx_costs (X, CODE, OUTER_CODE);
02421
02422
02423 #define MEMORY_MOVE_COST(M, CLASS, IN) \
02424 (TARGET_ARM ? 10 : \
02425 ((GET_MODE_SIZE (M) < 4 ? 8 : 2 * GET_MODE_SIZE (M)) \
02426 * (CLASS == LO_REGS ? 1 : 2)))
02427
02428
02429
02430
02431
02432 #define ARM_ADDRESS_COST(X) \
02433 (10 - ((GET_CODE (X) == MEM || GET_CODE (X) == LABEL_REF \
02434 || GET_CODE (X) == SYMBOL_REF) \
02435 ? 0 \
02436 : ((GET_CODE (X) == PRE_INC || GET_CODE (X) == PRE_DEC \
02437 || GET_CODE (X) == POST_INC || GET_CODE (X) == POST_DEC) \
02438 ? 10 \
02439 : (((GET_CODE (X) == PLUS || GET_CODE (X) == MINUS) \
02440 ? 6 + (GET_CODE (XEXP (X, 1)) == CONST_INT ? 2 \
02441 : ((GET_RTX_CLASS (GET_CODE (XEXP (X, 0))) == '2' \
02442 || GET_RTX_CLASS (GET_CODE (XEXP (X, 0))) == 'c' \
02443 || GET_RTX_CLASS (GET_CODE (XEXP (X, 1))) == '2' \
02444 || GET_RTX_CLASS (GET_CODE (XEXP (X, 1))) == 'c') \
02445 ? 1 : 0)) \
02446 : 4)))))
02447
02448 #define THUMB_ADDRESS_COST(X) \
02449 ((GET_CODE (X) == REG \
02450 || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == REG \
02451 && GET_CODE (XEXP (X, 1)) == CONST_INT)) \
02452 ? 1 : 2)
02453
02454 #define ADDRESS_COST(X) \
02455 (TARGET_ARM ? ARM_ADDRESS_COST (X) : THUMB_ADDRESS_COST (X))
02456
02457
02458
02459 #define BRANCH_COST \
02460 (TARGET_ARM ? 4 : (optimize > 1 ? 1 : 0))
02461
02462
02463
02464
02465
02466 extern int arm_pic_register;
02467
02468
02469 extern const char * arm_pic_register_string;
02470
02471
02472
02473 #define PIC_OFFSET_TABLE_REGNUM arm_pic_register
02474
02475 #define FINALIZE_PIC arm_finalize_pic (1)
02476
02477
02478
02479 #define LEGITIMATE_PIC_OPERAND_P(X) \
02480 ( ! symbol_mentioned_p (X) \
02481 && ! label_mentioned_p (X) \
02482 && (! CONSTANT_POOL_ADDRESS_P (X) \
02483 || ( ! symbol_mentioned_p (get_pool_constant (X)) \
02484 && ! label_mentioned_p (get_pool_constant (X)))))
02485
02486
02487
02488
02489 extern int making_const_table;
02490
02491
02492 #define REGISTER_TARGET_PRAGMAS(PFILE) do { \
02493 cpp_register_pragma (PFILE, 0, "long_calls", arm_pr_long_calls); \
02494 cpp_register_pragma (PFILE, 0, "no_long_calls", arm_pr_no_long_calls); \
02495 cpp_register_pragma (PFILE, 0, "long_calls_off", arm_pr_long_calls_off); \
02496 } while (0)
02497
02498
02499
02500
02501
02502
02503
02504
02505
02506
02507 #define EXTRA_CC_MODES \
02508 CC(CC_NOOVmode, "CC_NOOV") \
02509 CC(CC_Zmode, "CC_Z") \
02510 CC(CC_SWPmode, "CC_SWP") \
02511 CC(CCFPmode, "CCFP") \
02512 CC(CCFPEmode, "CCFPE") \
02513 CC(CC_DNEmode, "CC_DNE") \
02514 CC(CC_DEQmode, "CC_DEQ") \
02515 CC(CC_DLEmode, "CC_DLE") \
02516 CC(CC_DLTmode, "CC_DLT") \
02517 CC(CC_DGEmode, "CC_DGE") \
02518 CC(CC_DGTmode, "CC_DGT") \
02519 CC(CC_DLEUmode, "CC_DLEU") \
02520 CC(CC_DLTUmode, "CC_DLTU") \
02521 CC(CC_DGEUmode, "CC_DGEU") \
02522 CC(CC_DGTUmode, "CC_DGTU") \
02523 CC(CC_Cmode, "CC_C")
02524
02525 #define SELECT_CC_MODE(OP, X, Y) arm_select_cc_mode (OP, X, Y)
02526
02527 #define REVERSIBLE_CC_MODE(MODE) ((MODE) != CCFPEmode)
02528
02529 #define CANONICALIZE_COMPARISON(CODE, OP0, OP1) \
02530 do \
02531 { \
02532 if (GET_CODE (OP1) == CONST_INT \
02533 && ! (const_ok_for_arm (INTVAL (OP1)) \
02534 || (const_ok_for_arm (- INTVAL (OP1))))) \
02535 { \
02536 rtx const_op = OP1; \
02537 CODE = arm_canonicalize_comparison ((CODE), &const_op); \
02538 OP1 = const_op; \
02539 } \
02540 } \
02541 while (0)
02542
02543 #define STORE_FLAG_VALUE 1
02544
02545
02546
02547
02548
02549
02550
02551 #define MACHINE_DEPENDENT_REORG(INSN) \
02552 arm_reorg (INSN); \
02553
02554 #undef ASM_APP_OFF
02555 #define ASM_APP_OFF (TARGET_THUMB ? "\t.code\t16\n" : "")
02556
02557
02558 #ifndef ASM_OUTPUT_INTERNAL_LABEL
02559 #define ASM_OUTPUT_INTERNAL_LABEL(STREAM, PREFIX, NUM) \
02560 do \
02561 { \
02562 char * s = (char *) alloca (40 + strlen (PREFIX)); \
02563 \
02564 if (arm_ccfsm_state == 3 && arm_target_label == (NUM) \
02565 && !strcmp (PREFIX, "L")) \
02566 { \
02567 arm_ccfsm_state = 0; \
02568 arm_target_insn = NULL; \
02569 } \
02570 ASM_GENERATE_INTERNAL_LABEL (s, (PREFIX), (NUM)); \
02571 ASM_OUTPUT_LABEL (STREAM, s); \
02572 } \
02573 while (0)
02574 #endif
02575
02576
02577 #define ASM_OUTPUT_REG_PUSH(STREAM, REGNO) \
02578 if (TARGET_ARM) \
02579 asm_fprintf (STREAM,"\tstmfd\t%r!,{%r}\n", \
02580 STACK_POINTER_REGNUM, REGNO); \
02581 else \
02582 asm_fprintf (STREAM, "\tpush {%r}\n", REGNO)
02583
02584
02585 #define ASM_OUTPUT_REG_POP(STREAM, REGNO) \
02586 if (TARGET_ARM) \
02587 asm_fprintf (STREAM, "\tldmfd\t%r!,{%r}\n", \
02588 STACK_POINTER_REGNUM, REGNO); \
02589 else \
02590 asm_fprintf (STREAM, "\tpop {%r}\n", REGNO)
02591
02592
02593
02594 #undef ASM_OUTPUT_CASE_LABEL
02595 #define ASM_OUTPUT_CASE_LABEL(FILE, PREFIX, NUM, JUMPTABLE) \
02596 do \
02597 { \
02598 if (TARGET_THUMB) \
02599 ASM_OUTPUT_ALIGN (FILE, 2); \
02600 ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM); \
02601 } \
02602 while (0)
02603
02604 #define ARM_DECLARE_FUNCTION_NAME(STREAM, NAME, DECL) \
02605 do \
02606 { \
02607 if (TARGET_THUMB) \
02608 { \
02609 if (is_called_in_ARM_mode (DECL)) \
02610 fprintf (STREAM, "\t.code 32\n") ; \
02611 else \
02612 fprintf (STREAM, "\t.thumb_func\n") ; \
02613 } \
02614 if (TARGET_POKE_FUNCTION_NAME) \
02615 arm_poke_function_name (STREAM, (char *) NAME); \
02616 } \
02617 while (0)
02618
02619
02620 #define ASM_OUTPUT_DEF_FROM_DECLS(FILE, DECL1, DECL2) \
02621 do \
02622 { \
02623 const char *const LABEL1 = XSTR (XEXP (DECL_RTL (decl), 0), 0); \
02624 const char *const LABEL2 = IDENTIFIER_POINTER (DECL2); \
02625 \
02626 if (TARGET_THUMB && TREE_CODE (DECL1) == FUNCTION_DECL) \
02627 { \
02628 fprintf (FILE, "\t.thumb_set "); \
02629 assemble_name (FILE, LABEL1); \
02630 fprintf (FILE, ","); \
02631 assemble_name (FILE, LABEL2); \
02632 fprintf (FILE, "\n"); \
02633 } \
02634 else \
02635 ASM_OUTPUT_DEF (FILE, LABEL1, LABEL2); \
02636 } \
02637 while (0)
02638
02639 #ifdef HAVE_GAS_MAX_SKIP_P2ALIGN
02640
02641
02642
02643 #define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \
02644 if ((LOG) != 0) \
02645 { \
02646 if ((MAX_SKIP) == 0) \
02647 fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
02648 else \
02649 fprintf ((FILE), "\t.p2align %d,,%d\n", \
02650 (LOG), (MAX_SKIP)); \
02651 }
02652 #endif
02653
02654
02655
02656 #define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \
02657 if (TARGET_ARM && optimize) \
02658 arm_final_prescan_insn (INSN); \
02659 else if (TARGET_THUMB) \
02660 thumb_final_prescan_insn (INSN)
02661
02662 #define PRINT_OPERAND_PUNCT_VALID_P(CODE) \
02663 (CODE == '@' || CODE == '|' \
02664 || (TARGET_ARM && (CODE == '?')) \
02665 || (TARGET_THUMB && (CODE == '_')))
02666
02667
02668 #define PRINT_OPERAND(STREAM, X, CODE) \
02669 arm_print_operand (STREAM, X, CODE)
02670
02671 #define ARM_SIGN_EXTEND(x) ((HOST_WIDE_INT) \
02672 (HOST_BITS_PER_WIDE_INT <= 32 ? (unsigned HOST_WIDE_INT) (x) \
02673 : ((((unsigned HOST_WIDE_INT)(x)) & (unsigned HOST_WIDE_INT) 0xffffffff) |\
02674 ((((unsigned HOST_WIDE_INT)(x)) & (unsigned HOST_WIDE_INT) 0x80000000) \
02675 ? ((~ (unsigned HOST_WIDE_INT) 0) \
02676 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) \
02677 : 0))))
02678
02679
02680 #define ARM_PRINT_OPERAND_ADDRESS(STREAM, X) \
02681 { \
02682 int is_minus = GET_CODE (X) == MINUS; \
02683 \
02684 if (GET_CODE (X) == REG) \
02685 asm_fprintf (STREAM, "[%r, #0]", REGNO (X)); \
02686 else if (GET_CODE (X) == PLUS || is_minus) \
02687 { \
02688 rtx base = XEXP (X, 0); \
02689 rtx index = XEXP (X, 1); \
02690 HOST_WIDE_INT offset = 0; \
02691 if (GET_CODE (base) != REG) \
02692 { \
02693 \
02694 \
02695 rtx temp = base; \
02696 base = index; \
02697 index = temp; \
02698 } \
02699 switch (GET_CODE (index)) \
02700 { \
02701 case CONST_INT: \
02702 offset = INTVAL (index); \
02703 if (is_minus) \
02704 offset = -offset; \
02705 asm_fprintf (STREAM, "[%r, #%d]", \
02706 REGNO (base), offset); \
02707 break; \
02708 \
02709 case REG: \
02710 asm_fprintf (STREAM, "[%r, %s%r]", \
02711 REGNO (base), is_minus ? "-" : "", \
02712 REGNO (index)); \
02713 break; \
02714 \
02715 case MULT: \
02716 case ASHIFTRT: \
02717 case LSHIFTRT: \
02718 case ASHIFT: \
02719 case ROTATERT: \
02720 { \
02721 asm_fprintf (STREAM, "[%r, %s%r", \
02722 REGNO (base), is_minus ? "-" : "", \
02723 REGNO (XEXP (index, 0))); \
02724 arm_print_operand (STREAM, index, 'S'); \
02725 fputs ("]", STREAM); \
02726 break; \
02727 } \
02728 \
02729 default: \
02730 abort(); \
02731 } \
02732 } \
02733 else if ( GET_CODE (X) == PRE_INC || GET_CODE (X) == POST_INC\
02734 || GET_CODE (X) == PRE_DEC || GET_CODE (X) == POST_DEC)\
02735 { \
02736 extern int output_memory_reference_mode; \
02737 \
02738 if (GET_CODE (XEXP (X, 0)) != REG) \
02739 abort (); \
02740 \
02741 if (GET_CODE (X) == PRE_DEC || GET_CODE (X) == PRE_INC) \
02742 asm_fprintf (STREAM, "[%r, #%s%d]!", \
02743 REGNO (XEXP (X, 0)), \
02744 GET_CODE (X) == PRE_DEC ? "-" : "", \
02745 GET_MODE_SIZE (output_memory_reference_mode));\
02746 else \
02747 asm_fprintf (STREAM, "[%r], #%s%d", \
02748 REGNO (XEXP (X, 0)), \
02749 GET_CODE (X) == POST_DEC ? "-" : "", \
02750 GET_MODE_SIZE (output_memory_reference_mode));\
02751 } \
02752 else output_addr_const (STREAM, X); \
02753 }
02754
02755 #define THUMB_PRINT_OPERAND_ADDRESS(STREAM, X) \
02756 { \
02757 if (GET_CODE (X) == REG) \
02758 asm_fprintf (STREAM, "[%r]", REGNO (X)); \
02759 else if (GET_CODE (X) == POST_INC) \
02760 asm_fprintf (STREAM, "%r!", REGNO (XEXP (X, 0))); \
02761 else if (GET_CODE (X) == PLUS) \
02762 { \
02763 if (GET_CODE (XEXP (X, 1)) == CONST_INT) \
02764 asm_fprintf (STREAM, "[%r, #%d]", \
02765 REGNO (XEXP (X, 0)), \
02766 (int) INTVAL (XEXP (X, 1))); \
02767 else \
02768 asm_fprintf (STREAM, "[%r, %r]", \
02769 REGNO (XEXP (X, 0)), \
02770 REGNO (XEXP (X, 1))); \
02771 } \
02772 else \
02773 output_addr_const (STREAM, X); \
02774 }
02775
02776 #define PRINT_OPERAND_ADDRESS(STREAM, X) \
02777 if (TARGET_ARM) \
02778 ARM_PRINT_OPERAND_ADDRESS (STREAM, X) \
02779 else \
02780 THUMB_PRINT_OPERAND_ADDRESS (STREAM, X)
02781
02782
02783
02784 #define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
02785 do \
02786 { \
02787 int mi_delta = (DELTA); \
02788 const char *const mi_op = mi_delta < 0 ? "sub" : "add"; \
02789 int shift = 0; \
02790 int this_regno = (aggregate_value_p (TREE_TYPE (TREE_TYPE (FUNCTION))) \
02791 ? 1 : 0); \
02792 if (mi_delta < 0) \
02793 mi_delta = - mi_delta; \
02794 while (mi_delta != 0) \
02795 { \
02796 if ((mi_delta & (3 << shift)) == 0) \
02797 shift += 2; \
02798 else \
02799 { \
02800 asm_fprintf (FILE, "\t%s\t%r, %r, #%d\n", \
02801 mi_op, this_regno, this_regno, \
02802 mi_delta & (0xff << shift)); \
02803 mi_delta &= ~(0xff << shift); \
02804 shift += 8; \
02805 } \
02806 } \
02807 fputs ("\tb\t", FILE); \
02808 assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0)); \
02809 if (NEED_PLT_RELOC) \
02810 fputs ("(PLT)", FILE); \
02811 fputc ('\n', FILE); \
02812 } \
02813 while (0)
02814
02815
02816
02817
02818 #define RETURN_ADDR_RTX(COUNT, FRAME) \
02819 arm_return_addr (COUNT, FRAME)
02820
02821
02822
02823 #define RETURN_ADDR_MASK26 (0x03fffffc)
02824
02825
02826
02827
02828 #define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, LR_REGNUM)
02829 #define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (LR_REGNUM)
02830
02831
02832
02833 #define MASK_RETURN_ADDR \
02834
02835
02836
02837 \
02838 ((!TARGET_APCS_32) ? (GEN_INT (RETURN_ADDR_MASK26)) \
02839 : (GEN_INT ((unsigned long)0xffffffff)))
02840
02841
02842
02843 #define PREDICATE_CODES \
02844 {"s_register_operand", {SUBREG, REG}}, \
02845 {"arm_hard_register_operand", {REG}}, \
02846 {"f_register_operand", {SUBREG, REG}}, \
02847 {"arm_add_operand", {SUBREG, REG, CONST_INT}}, \
02848 {"fpu_add_operand", {SUBREG, REG, CONST_DOUBLE}}, \
02849 {"fpu_rhs_operand", {SUBREG, REG, CONST_DOUBLE}}, \
02850 {"arm_rhs_operand", {SUBREG, REG, CONST_INT}}, \
02851 {"arm_not_operand", {SUBREG, REG, CONST_INT}}, \
02852 {"reg_or_int_operand", {SUBREG, REG, CONST_INT}}, \
02853 {"index_operand", {SUBREG, REG, CONST_INT}}, \
02854 {"thumb_cmp_operand", {SUBREG, REG, CONST_INT}}, \
02855 {"offsettable_memory_operand", {MEM}}, \
02856 {"bad_signed_byte_operand", {MEM}}, \
02857 {"alignable_memory_operand", {MEM}}, \
02858 {"shiftable_operator", {PLUS, MINUS, AND, IOR, XOR}}, \
02859 {"minmax_operator", {SMIN, SMAX, UMIN, UMAX}}, \
02860 {"shift_operator", {ASHIFT, ASHIFTRT, LSHIFTRT, ROTATERT, MULT}}, \
02861 {"di_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE, MEM}}, \
02862 {"nonimmediate_di_operand", {SUBREG, REG, MEM}}, \
02863 {"soft_df_operand", {SUBREG, REG, CONST_DOUBLE, MEM}}, \
02864 {"nonimmediate_soft_df_operand", {SUBREG, REG, MEM}}, \
02865 {"load_multiple_operation", {PARALLEL}}, \
02866 {"store_multiple_operation", {PARALLEL}}, \
02867 {"equality_operator", {EQ, NE}}, \
02868 {"arm_comparison_operator", {EQ, NE, LE, LT, GE, GT, GEU, GTU, LEU, \
02869 LTU, UNORDERED, ORDERED, UNLT, UNLE, \
02870 UNGE, UNGT}}, \
02871 {"arm_rhsm_operand", {SUBREG, REG, CONST_INT, MEM}}, \
02872 {"const_shift_operand", {CONST_INT}}, \
02873 {"multi_register_push", {PARALLEL}}, \
02874 {"cc_register", {REG}}, \
02875 {"logical_binary_operator", {AND, IOR, XOR}}, \
02876 {"dominant_cc_register", {REG}},
02877
02878
02879
02880
02881
02882 #define SPECIAL_MODE_PREDICATES \
02883 "cc_register", "dominant_cc_register",
02884
02885 enum arm_builtins
02886 {
02887 ARM_BUILTIN_CLZ,
02888 ARM_BUILTIN_MAX
02889 };
02890 #endif