diff options
author | Ian Lance Taylor <iant@golang.org> | 2020-12-07 10:45:52 -0800 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2020-12-07 10:45:52 -0800 |
commit | 45c32be1f96ace25b66c34a84818dc5e07e9d516 (patch) | |
tree | 2a6658e3df17c11dd8d74d9c7403c9bc69678010 /gcc/config | |
parent | 945ae3ab27757d3261d99446f96105c5ebe70247 (diff) | |
parent | b737b70fad398728f6006e8397d1bb31ccea4ce7 (diff) | |
download | gcc-45c32be1f96ace25b66c34a84818dc5e07e9d516.zip gcc-45c32be1f96ace25b66c34a84818dc5e07e9d516.tar.gz gcc-45c32be1f96ace25b66c34a84818dc5e07e9d516.tar.bz2 |
Merge from trunk revision b737b70fad398728f6006e8397d1bb31ccea4ce7.
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/i386/driver-i386.c | 5 | ||||
-rw-r--r-- | gcc/config/i386/i386-c.c | 7 | ||||
-rw-r--r-- | gcc/config/i386/i386-features.c | 3 | ||||
-rw-r--r-- | gcc/config/i386/i386-options.c | 4 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 5 | ||||
-rw-r--r-- | gcc/config/i386/i386.h | 2 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 8 | ||||
-rw-r--r-- | gcc/config/i386/x86-tune-sched.c | 2 | ||||
-rw-r--r-- | gcc/config/i386/x86-tune.def | 2 | ||||
-rw-r--r-- | gcc/config/i386/znver1.md | 353 | ||||
-rw-r--r-- | gcc/config/pdp11/pdp11.md | 4 | ||||
-rw-r--r-- | gcc/config/rs6000/xcoff.h | 4 | ||||
-rw-r--r-- | gcc/config/s390/s390.c | 2 | ||||
-rw-r--r-- | gcc/config/vax/builtins.md | 269 | ||||
-rw-r--r-- | gcc/config/vax/constraints.md | 4 | ||||
-rw-r--r-- | gcc/config/vax/elf.h | 13 | ||||
-rw-r--r-- | gcc/config/vax/netbsd-elf.h | 4 | ||||
-rw-r--r-- | gcc/config/vax/predicates.md | 70 | ||||
-rw-r--r-- | gcc/config/vax/vax-modes.def | 11 | ||||
-rw-r--r-- | gcc/config/vax/vax-protos.h | 4 | ||||
-rw-r--r-- | gcc/config/vax/vax.c | 353 | ||||
-rw-r--r-- | gcc/config/vax/vax.h | 41 | ||||
-rw-r--r-- | gcc/config/vax/vax.md | 2034 |
23 files changed, 2494 insertions, 710 deletions
diff --git a/gcc/config/i386/driver-i386.c b/gcc/config/i386/driver-i386.c index ecdad57..2bfa037 100644 --- a/gcc/config/i386/driver-i386.c +++ b/gcc/config/i386/driver-i386.c @@ -455,6 +455,8 @@ const char *host_detect_local_cpu (int argc, const char **argv) processor = PROCESSOR_GEODE; else if (has_feature (FEATURE_MOVBE) && family == 22) processor = PROCESSOR_BTVER2; + else if (has_feature (FEATURE_VAES)) + processor = PROCESSOR_ZNVER3; else if (has_feature (FEATURE_CLWB)) processor = PROCESSOR_ZNVER2; else if (has_feature (FEATURE_CLZERO)) @@ -753,6 +755,9 @@ const char *host_detect_local_cpu (int argc, const char **argv) case PROCESSOR_ZNVER2: cpu = "znver2"; break; + case PROCESSOR_ZNVER3: + cpu = "znver3"; + break; case PROCESSOR_BTVER1: cpu = "btver1"; break; diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c index 87b3a2b..6d690e0 100644 --- a/gcc/config/i386/i386-c.c +++ b/gcc/config/i386/i386-c.c @@ -128,6 +128,10 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag, def_or_undef (parse_in, "__znver2"); def_or_undef (parse_in, "__znver2__"); break; + case PROCESSOR_ZNVER3: + def_or_undef (parse_in, "__znver3"); + def_or_undef (parse_in, "__znver3__"); + break; case PROCESSOR_BTVER1: def_or_undef (parse_in, "__btver1"); def_or_undef (parse_in, "__btver1__"); @@ -315,6 +319,9 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag, case PROCESSOR_ZNVER2: def_or_undef (parse_in, "__tune_znver2__"); break; + case PROCESSOR_ZNVER3: + def_or_undef (parse_in, "__tune_znver3__"); + break; case PROCESSOR_BTVER1: def_or_undef (parse_in, "__tune_btver1__"); break; diff --git a/gcc/config/i386/i386-features.c b/gcc/config/i386/i386-features.c index ff6676f..c61685b 100644 --- a/gcc/config/i386/i386-features.c +++ b/gcc/config/i386/i386-features.c @@ -1266,9 +1266,10 @@ pseudo_reg_set (rtx_insn *insn) return NULL; /* Check pseudo register push first. */ + machine_mode mode = TARGET_64BIT ? TImode : DImode; if (REG_P (SET_SRC (set)) && !HARD_REGISTER_P (SET_SRC (set)) - && push_operand (SET_DEST (set), GET_MODE (SET_DEST (set)))) + && push_operand (SET_DEST (set), mode)) return set; df_ref ref; diff --git a/gcc/config/i386/i386-options.c b/gcc/config/i386/i386-options.c index dc07697..40714c8 100644 --- a/gcc/config/i386/i386-options.c +++ b/gcc/config/i386/i386-options.c @@ -147,11 +147,12 @@ along with GCC; see the file COPYING3. If not see #define m_BDVER4 (HOST_WIDE_INT_1U<<PROCESSOR_BDVER4) #define m_ZNVER1 (HOST_WIDE_INT_1U<<PROCESSOR_ZNVER1) #define m_ZNVER2 (HOST_WIDE_INT_1U<<PROCESSOR_ZNVER2) +#define m_ZNVER3 (HOST_WIDE_INT_1U<<PROCESSOR_ZNVER3) #define m_BTVER1 (HOST_WIDE_INT_1U<<PROCESSOR_BTVER1) #define m_BTVER2 (HOST_WIDE_INT_1U<<PROCESSOR_BTVER2) #define m_BDVER (m_BDVER1 | m_BDVER2 | m_BDVER3 | m_BDVER4) #define m_BTVER (m_BTVER1 | m_BTVER2) -#define m_ZNVER (m_ZNVER1 | m_ZNVER2) +#define m_ZNVER (m_ZNVER1 | m_ZNVER2 | m_ZNVER3) #define m_AMD_MULTIPLE (m_ATHLON_K8 | m_AMDFAM10 | m_BDVER | m_BTVER \ | m_ZNVER) @@ -745,6 +746,7 @@ static const struct processor_costs *processor_cost_table[] = &btver1_cost, &btver2_cost, &znver1_cost, + &znver2_cost, &znver2_cost }; diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 6321678..3a57710 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -21976,8 +21976,9 @@ ix86_reassociation_width (unsigned int op, machine_mode mode) /* Integer vector instructions execute in FP unit and can execute 3 additions and one multiplication per cycle. */ - if ((ix86_tune == PROCESSOR_ZNVER1 || ix86_tune == PROCESSOR_ZNVER2) - && INTEGRAL_MODE_P (mode) && op != PLUS && op != MINUS) + if ((ix86_tune == PROCESSOR_ZNVER1 || ix86_tune == PROCESSOR_ZNVER2 + || ix86_tune == PROCESSOR_ZNVER3) + && INTEGRAL_MODE_P (mode) && op != PLUS && op != MINUS) return 1; /* Account for targets that splits wide vectors into multiple parts. */ diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index b8ae16e..5680fdc 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -484,6 +484,7 @@ extern const struct processor_costs ix86_size_cost; #define TARGET_BTVER2 (ix86_tune == PROCESSOR_BTVER2) #define TARGET_ZNVER1 (ix86_tune == PROCESSOR_ZNVER1) #define TARGET_ZNVER2 (ix86_tune == PROCESSOR_ZNVER2) +#define TARGET_ZNVER3 (ix86_tune == PROCESSOR_ZNVER3) /* Feature tests against the various tunings. */ enum ix86_tune_indices { @@ -2397,6 +2398,7 @@ enum processor_type PROCESSOR_BTVER2, PROCESSOR_ZNVER1, PROCESSOR_ZNVER2, + PROCESSOR_ZNVER3, PROCESSOR_max }; diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 129d47b..21f0044 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -458,7 +458,7 @@ ;; Processor type. (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem, atom,slm,glm,haswell,generic,amdfam10,bdver1,bdver2,bdver3, - bdver4,btver2,znver1,znver2" + bdver4,btver2,znver1,znver2,znver3" (const (symbol_ref "ix86_schedule"))) ;; A basic instruction type. Refinements due to arguments to be @@ -11988,8 +11988,7 @@ [(set (match_dup 4) (match_dup 1)) (set (match_dup 0) (any_rotate:SWI48 (match_dup 4) - (subreg:QI - (and:SI (match_dup 2) (match_dup 3)) 0)))] + (subreg:QI (match_dup 2) 0)))] "operands[4] = gen_reg_rtx (<MODE>mode);") (define_insn_and_split "*<rotate_insn><mode>3_mask_1" @@ -12023,8 +12022,7 @@ == GET_MODE_BITSIZE (<MODE>mode) - 1" [(set (match_dup 4) (match_dup 1)) (set (match_dup 0) - (any_rotate:SWI48 (match_dup 4) - (and:QI (match_dup 2) (match_dup 3))))] + (any_rotate:SWI48 (match_dup 4) (match_dup 2)))] "operands[4] = gen_reg_rtx (<MODE>mode);") ;; Implement rotation using two double-precision diff --git a/gcc/config/i386/x86-tune-sched.c b/gcc/config/i386/x86-tune-sched.c index d4d8a12..404b5b1 100644 --- a/gcc/config/i386/x86-tune-sched.c +++ b/gcc/config/i386/x86-tune-sched.c @@ -66,6 +66,7 @@ ix86_issue_rate (void) case PROCESSOR_BDVER4: case PROCESSOR_ZNVER1: case PROCESSOR_ZNVER2: + case PROCESSOR_ZNVER3: case PROCESSOR_CORE2: case PROCESSOR_NEHALEM: case PROCESSOR_SANDYBRIDGE: @@ -396,6 +397,7 @@ ix86_adjust_cost (rtx_insn *insn, int dep_type, rtx_insn *dep_insn, int cost, case PROCESSOR_ZNVER1: case PROCESSOR_ZNVER2: + case PROCESSOR_ZNVER3: /* Stack engine allows to execute push&pop instructions in parall. */ if ((insn_type == TYPE_PUSH || insn_type == TYPE_POP) && (dep_insn_type == TYPE_PUSH || dep_insn_type == TYPE_POP)) diff --git a/gcc/config/i386/x86-tune.def b/gcc/config/i386/x86-tune.def index 6eff825..ed4d74c 100644 --- a/gcc/config/i386/x86-tune.def +++ b/gcc/config/i386/x86-tune.def @@ -444,7 +444,7 @@ DEF_TUNE (X86_TUNE_AVOID_128FMA_CHAINS, "avoid_fma_chains", m_ZNVER) /* X86_TUNE_AVOID_256FMA_CHAINS: Avoid creating loops with tight 256bit or smaller FMA chain. */ -DEF_TUNE (X86_TUNE_AVOID_256FMA_CHAINS, "avoid_fma256_chains", m_ZNVER2) +DEF_TUNE (X86_TUNE_AVOID_256FMA_CHAINS, "avoid_fma256_chains", m_ZNVER2 | m_ZNVER3) /*****************************************************************************/ /* AVX instruction selection tuning (some of SSE flags affects AVX, too) */ diff --git a/gcc/config/i386/znver1.md b/gcc/config/i386/znver1.md index 6812a3d..b0edfab 100644 --- a/gcc/config/i386/znver1.md +++ b/gcc/config/i386/znver1.md @@ -21,7 +21,7 @@ (define_attr "znver1_decode" "direct,vector,double" (const_string "direct")) -;; AMD znver1 and znver2 Scheduling +;; AMD znver1, znver2 and znver3 Scheduling ;; Modeling automatons for zen decoders, integer execution pipes, ;; AGU pipes and floating point execution units. (define_automaton "znver1, znver1_ieu, znver1_fp, znver1_agu") @@ -52,7 +52,7 @@ (define_cpu_unit "znver1-ieu3" "znver1_ieu") (define_reservation "znver1-ieu" "znver1-ieu0|znver1-ieu1|znver1-ieu2|znver1-ieu3") -;; 2 AGU pipes in znver1 and 3 AGU pipes in znver2 +;; 2 AGU pipes in znver1 and 3 AGU pipes in znver2 and znver3 ;; According to CPU diagram last AGU unit is used only for stores. (define_cpu_unit "znver1-agu0" "znver1_agu") (define_cpu_unit "znver1-agu1" "znver1_agu") @@ -63,7 +63,7 @@ ;; Load is 4 cycles. We do not model reservation of load unit. ;;(define_reservation "znver1-load" "znver1-agu-reserve, nothing, nothing, nothing") (define_reservation "znver1-load" "znver1-agu-reserve") -;; Store operations differs between znver1 and znver2 because extra AGU +;; Store operations differs between znver1, znver2 and znver3 because extra AGU ;; was added. (define_reservation "znver1-store" "znver1-agu-reserve") (define_reservation "znver2-store" "znver2-store-agu-reserve") @@ -77,6 +77,7 @@ (define_reservation "znver2-ivector" "znver1-ieu0+znver1-ieu1 +znver1-ieu2+znver1-ieu3 +znver1-agu0+znver1-agu1+znver2-agu2") + ;; Floating point unit 4 FP pipes. (define_cpu_unit "znver1-fp0" "znver1_fp") (define_cpu_unit "znver1-fp1" "znver1_fp") @@ -99,7 +100,7 @@ "znver1-double,znver1-store,znver1-ieu0|znver1-ieu3") (define_insn_reservation "znver2_call" 1 - (and (eq_attr "cpu" "znver2") + (and (eq_attr "cpu" "znver2,znver3") (eq_attr "type" "call,callv")) "znver1-double,znver2-store,znver1-ieu0|znver1-ieu3") @@ -110,10 +111,10 @@ (eq_attr "memory" "store"))) "znver1-direct,znver1-store") (define_insn_reservation "znver2_push" 1 - (and (eq_attr "cpu" "znver2") + (and (eq_attr "cpu" "znver2,znver3") (and (eq_attr "type" "push") (eq_attr "memory" "store"))) - "znver1-direct,znver1-store") + "znver1-direct,znver2-store") (define_insn_reservation "znver1_push_load" 4 (and (eq_attr "cpu" "znver1") @@ -121,13 +122,13 @@ (eq_attr "memory" "both"))) "znver1-direct,znver1-load,znver1-store") (define_insn_reservation "znver2_push_load" 4 - (and (eq_attr "cpu" "znver2") + (and (eq_attr "cpu" "znver2,znver3") (and (eq_attr "type" "push") (eq_attr "memory" "both"))) "znver1-direct,znver1-load,znver2-store") (define_insn_reservation "znver1_pop" 4 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "type" "pop") (eq_attr "memory" "load"))) "znver1-direct,znver1-load") @@ -138,7 +139,7 @@ (eq_attr "memory" "both"))) "znver1-direct,znver1-load,znver1-store") (define_insn_reservation "znver2_pop_mem" 4 - (and (eq_attr "cpu" "znver2") + (and (eq_attr "cpu" "znver2,znver3") (and (eq_attr "type" "pop") (eq_attr "memory" "both"))) "znver1-direct,znver1-load,znver2-store") @@ -149,7 +150,7 @@ (eq_attr "type" "leave")) "znver1-double,znver1-ieu, znver1-store") (define_insn_reservation "znver2_leave" 1 - (and (eq_attr "cpu" "znver2") + (and (eq_attr "cpu" "znver2,znver3") (eq_attr "type" "leave")) "znver1-double,znver1-ieu, znver2-store") @@ -157,13 +158,13 @@ ;; Multiplications ;; Reg operands (define_insn_reservation "znver1_imul" 3 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "type" "imul") (eq_attr "memory" "none"))) "znver1-direct,znver1-ieu1") (define_insn_reservation "znver1_imul_mem" 7 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "type" "imul") (eq_attr "memory" "!none"))) "znver1-direct,znver1-load, znver1-ieu1") @@ -227,6 +228,62 @@ (eq_attr "memory" "none")))) "znver1-direct,znver1-load,znver1-ieu2*12") +(define_insn_reservation "znver3_idiv_DI" 18 + (and (eq_attr "cpu" "znver3") + (and (eq_attr "type" "idiv") + (and (eq_attr "mode" "DI") + (eq_attr "memory" "none")))) + "znver1-double,znver1-ieu2*18") + +(define_insn_reservation "znver3_idiv_SI" 12 + (and (eq_attr "cpu" "znver3") + (and (eq_attr "type" "idiv") + (and (eq_attr "mode" "SI") + (eq_attr "memory" "none")))) + "znver1-double,znver1-ieu2*12") + +(define_insn_reservation "znver3_idiv_HI" 10 + (and (eq_attr "cpu" "znver3") + (and (eq_attr "type" "idiv") + (and (eq_attr "mode" "HI") + (eq_attr "memory" "none")))) + "znver1-double,znver1-ieu2*10") + +(define_insn_reservation "znver3_idiv_QI" 9 + (and (eq_attr "cpu" "znver3") + (and (eq_attr "type" "idiv") + (and (eq_attr "mode" "QI") + (eq_attr "memory" "none")))) + "znver1-direct,znver1-ieu2*9") + +(define_insn_reservation "znver3_idiv_mem_DI" 22 + (and (eq_attr "cpu" "znver3") + (and (eq_attr "type" "idiv") + (and (eq_attr "mode" "DI") + (eq_attr "memory" "load")))) + "znver1-double,znver1-load,znver1-ieu2*22") + +(define_insn_reservation "znver3_idiv_mem_SI" 16 + (and (eq_attr "cpu" "znver3") + (and (eq_attr "type" "idiv") + (and (eq_attr "mode" "SI") + (eq_attr "memory" "load")))) + "znver1-double,znver1-load,znver1-ieu2*16") + +(define_insn_reservation "znver3_idiv_mem_HI" 14 + (and (eq_attr "cpu" "znver3") + (and (eq_attr "type" "idiv") + (and (eq_attr "mode" "HI") + (eq_attr "memory" "load")))) + "znver1-double,znver1-load,znver1-ieu2*10") + +(define_insn_reservation "znver3_idiv_mem_QI" 13 + (and (eq_attr "cpu" "znver3") + (and (eq_attr "type" "idiv") + (and (eq_attr "mode" "QI") + (eq_attr "memory" "load")))) + "znver1-direct,znver1-load,znver1-ieu2*9") + ;; STR ISHIFT which are micro coded. ;; Fix me: Latency need to be rechecked. (define_insn_reservation "znver1_str_ishift" 6 @@ -236,15 +293,16 @@ "znver1-vector,znver1-ivector") (define_insn_reservation "znver2_str_ishift" 3 - (and (eq_attr "cpu" "znver2") + (and (eq_attr "cpu" "znver2,znver3") (and (eq_attr "type" "ishift") (eq_attr "memory" "both,store"))) "znver1-vector,znver1-ivector") (define_insn_reservation "znver2_str_istr" 19 - (and (eq_attr "cpu" "znver2") + (and (eq_attr "cpu" "znver2,znver3") (and (eq_attr "type" "str") (eq_attr "memory" "both,store"))) "znver1-vector,znver1-ivector") + ;; MOV - integer moves (define_insn_reservation "znver1_load_imov_double" 2 (and (eq_attr "cpu" "znver1") @@ -254,14 +312,14 @@ "znver1-double,znver1-ieu|znver1-ieu") (define_insn_reservation "znver2_load_imov_double" 1 - (and (eq_attr "cpu" "znver2") + (and (eq_attr "cpu" "znver2,znver3") (and (eq_attr "znver1_decode" "double") (and (eq_attr "type" "imovx") (eq_attr "memory" "none")))) "znver1-double,znver1-ieu|znver1-ieu") (define_insn_reservation "znver1_load_imov_direct" 1 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "type" "imov,imovx") (eq_attr "memory" "none"))) "znver1-direct,znver1-ieu") @@ -274,7 +332,7 @@ "znver1-double,znver1-ieu|znver1-ieu,znver1-store") (define_insn_reservation "znver2_load_imov_double_store" 1 - (and (eq_attr "cpu" "znver2") + (and (eq_attr "cpu" "znver2,znver3") (and (eq_attr "znver1_decode" "double") (and (eq_attr "type" "imovx") (eq_attr "memory" "store")))) @@ -287,7 +345,7 @@ "znver1-direct,znver1-ieu,znver1-store") (define_insn_reservation "znver2_load_imov_direct_store" 1 - (and (eq_attr "cpu" "znver2") + (and (eq_attr "cpu" "znver2,znver3") (and (eq_attr "type" "imov,imovx") (eq_attr "memory" "store"))) "znver1-direct,znver1-ieu,znver2-store") @@ -300,14 +358,14 @@ "znver1-double,znver1-load,znver1-ieu|znver1-ieu") (define_insn_reservation "znver2_load_imov_double_load" 4 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver2,znver3") (and (eq_attr "znver1_decode" "double") (and (eq_attr "type" "imovx") (eq_attr "memory" "load")))) "znver1-double,znver1-load,znver1-ieu|znver1-ieu") (define_insn_reservation "znver1_load_imov_direct_load" 4 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "type" "imov,imovx") (eq_attr "memory" "load"))) "znver1-direct,znver1-load") @@ -315,13 +373,13 @@ ;; INTEGER/GENERAL instructions ;; register/imm operands only: ALU, ICMP, NEG, NOT, ROTATE, ISHIFT, TEST (define_insn_reservation "znver1_insn" 1 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "type" "alu,icmp,negnot,rotate,rotate1,ishift,ishift1,test,setcc,incdec,icmov") (eq_attr "memory" "none,unknown"))) "znver1-direct,znver1-ieu") (define_insn_reservation "znver1_insn_load" 5 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "type" "alu,icmp,negnot,rotate,rotate1,ishift,ishift1,test,setcc,incdec,icmov") (eq_attr "memory" "load"))) "znver1-direct,znver1-load,znver1-ieu") @@ -333,7 +391,7 @@ "znver1-direct,znver1-ieu,znver1-store") (define_insn_reservation "znver2_insn_store" 1 - (and (eq_attr "cpu" "znver2") + (and (eq_attr "cpu" "znver2,znver3") (and (eq_attr "type" "alu,icmp,negnot,rotate,rotate1,ishift1,test,setcc,incdec") (eq_attr "memory" "store"))) "znver1-direct,znver1-ieu,znver2-store") @@ -345,7 +403,7 @@ "znver1-direct,znver1-load,znver1-ieu,znver1-store") (define_insn_reservation "znver2_insn_both" 5 - (and (eq_attr "cpu" "znver2") + (and (eq_attr "cpu" "znver2,znver3") (and (eq_attr "type" "alu,icmp,negnot,rotate,rotate1,ishift1,test,setcc,incdec") (eq_attr "memory" "both"))) "znver1-direct,znver1-load,znver1-ieu,znver2-store") @@ -357,7 +415,7 @@ "znver1-vector,znver1-ivector") (define_insn_reservation "znver2_ieu_vector" 5 - (and (eq_attr "cpu" "znver2") + (and (eq_attr "cpu" "znver2,znver3") (eq_attr "type" "other,str,multi")) "znver1-vector,znver2-ivector") @@ -370,21 +428,21 @@ "znver1-vector,znver1-ivector") (define_insn_reservation "znver2_alu1_vector" 3 - (and (eq_attr "cpu" "znver2") + (and (eq_attr "cpu" "znver2,znver3") (and (eq_attr "znver1_decode" "vector") (and (eq_attr "type" "alu1") (eq_attr "memory" "none,unknown")))) "znver1-vector,znver2-ivector") (define_insn_reservation "znver1_alu1_double" 2 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "znver1_decode" "double") (and (eq_attr "type" "alu1") (eq_attr "memory" "none,unknown")))) "znver1-double,znver1-ieu") (define_insn_reservation "znver1_alu1_direct" 1 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "znver1_decode" "direct") (and (eq_attr "type" "alu1") (eq_attr "memory" "none,unknown")))) @@ -392,45 +450,45 @@ ;; Branches : Fix me need to model conditional branches. (define_insn_reservation "znver1_branch" 1 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "type" "ibr") - (eq_attr "memory" "none"))) + (eq_attr "memory" "none"))) "znver1-direct") ;; Indirect branches check latencies. (define_insn_reservation "znver1_indirect_branch_mem" 6 (and (eq_attr "cpu" "znver1") (and (eq_attr "type" "ibr") - (eq_attr "memory" "load"))) + (eq_attr "memory" "load"))) "znver1-vector,znver1-ivector") (define_insn_reservation "znver2_indirect_branch_mem" 6 - (and (eq_attr "cpu" "znver2") + (and (eq_attr "cpu" "znver2,znver3") (and (eq_attr "type" "ibr") - (eq_attr "memory" "load"))) + (eq_attr "memory" "load"))) "znver1-vector,znver2-ivector") ;; LEA executes in ALU units with 1 cycle latency. (define_insn_reservation "znver1_lea" 1 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (eq_attr "type" "lea")) "znver1-direct,znver1-ieu") ;; Other integer instrucions (define_insn_reservation "znver1_idirect" 1 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "unit" "integer,unknown") (eq_attr "memory" "none,unknown"))) "znver1-direct,znver1-ieu") ;; Floating point (define_insn_reservation "znver1_fp_cmov" 6 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (eq_attr "type" "fcmov")) "znver1-vector,znver1-fvector") (define_insn_reservation "znver1_fp_mov_direct_load" 8 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "znver1_decode" "direct") (and (eq_attr "type" "fmov") (eq_attr "memory" "load")))) @@ -443,41 +501,34 @@ (eq_attr "memory" "store")))) "znver1-direct,znver1-fp2|znver1-fp3,znver1-store") (define_insn_reservation "znver2_fp_mov_direct_store" 5 - (and (eq_attr "cpu" "znver2") + (and (eq_attr "cpu" "znver2,znver3") (and (eq_attr "znver1_decode" "direct") (and (eq_attr "type" "fmov") (eq_attr "memory" "store")))) "znver1-direct,znver1-fp2|znver1-fp3,znver2-store") (define_insn_reservation "znver1_fp_mov_double" 4 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "znver1_decode" "double") (and (eq_attr "type" "fmov") (eq_attr "memory" "none")))) "znver1-double,znver1-fp3") (define_insn_reservation "znver1_fp_mov_double_load" 12 - (and (eq_attr "cpu" "znver1") - (and (eq_attr "znver1_decode" "double") - (and (eq_attr "type" "fmov") - (eq_attr "memory" "load")))) - "znver1-double,znver1-load,znver1-fp3") - -(define_insn_reservation "znver2_fp_mov_double_load" 12 - (and (eq_attr "cpu" "znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "znver1_decode" "double") (and (eq_attr "type" "fmov") (eq_attr "memory" "load")))) "znver1-double,znver1-load,znver1-fp3") (define_insn_reservation "znver1_fp_mov_direct" 1 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (eq_attr "type" "fmov")) "znver1-direct,znver1-fp3") ;; TODO: AGU? (define_insn_reservation "znver1_fp_spc_direct" 5 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "type" "fpspc") (eq_attr "memory" "store"))) "znver1-direct,znver1-fp3,znver1-fp2") @@ -488,26 +539,26 @@ (eq_attr "type" "fpspc,mmxcvt,sselog1,ssemul,ssemov"))) "znver1-vector,znver1-fvector") (define_insn_reservation "znver2_fp_insn_vector" 6 - (and (eq_attr "cpu" "znver2") + (and (eq_attr "cpu" "znver2,znver3") (and (eq_attr "znver1_decode" "vector") (eq_attr "type" "fpspc,mmxcvt,sselog1,ssemul,ssemov"))) "znver1-vector,znver2-fvector") ;; FABS (define_insn_reservation "znver1_fp_fsgn" 1 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (eq_attr "type" "fsgn")) "znver1-direct,znver1-fp3") (define_insn_reservation "znver1_fp_fcmp" 2 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "memory" "none") (and (eq_attr "znver1_decode" "double") (eq_attr "type" "fcmp")))) "znver1-double,znver1-fp0,znver1-fp2") (define_insn_reservation "znver1_fp_fcmp_load" 9 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "memory" "none") (and (eq_attr "znver1_decode" "double") (eq_attr "type" "fcmp")))) @@ -515,32 +566,32 @@ ;;FADD FSUB FMUL (define_insn_reservation "znver1_fp_op_mul" 5 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "type" "fop,fmul") (eq_attr "memory" "none"))) "znver1-direct,znver1-fp0*5") (define_insn_reservation "znver1_fp_op_mul_load" 12 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "type" "fop,fmul") (eq_attr "memory" "load"))) "znver1-direct,znver1-load,znver1-fp0*5") (define_insn_reservation "znver1_fp_op_imul_load" 16 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "type" "fop,fmul") (and (eq_attr "fp_int_src" "true") (eq_attr "memory" "load")))) "znver1-double,znver1-load,znver1-fp3,znver1-fp0") (define_insn_reservation "znver1_fp_op_div" 15 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "type" "fdiv") (eq_attr "memory" "none"))) "znver1-direct,znver1-fp3*15") (define_insn_reservation "znver1_fp_op_div_load" 22 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "type" "fdiv") (eq_attr "memory" "load"))) "znver1-direct,znver1-load,znver1-fp3*15") @@ -553,62 +604,63 @@ "znver1-double,znver1-load,znver1-fp3*19") (define_insn_reservation "znver2_fp_op_idiv_load" 26 - (and (eq_attr "cpu" "znver2") + (and (eq_attr "cpu" "znver2,znver3") (and (eq_attr "type" "fdiv") (and (eq_attr "fp_int_src" "true") (eq_attr "memory" "load")))) "znver1-double,znver1-load,znver1-fp3*19") + ;; MMX, SSE, SSEn.n, AVX, AVX2 instructions (define_insn_reservation "znver1_fp_insn" 1 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (eq_attr "type" "mmx")) "znver1-direct,znver1-fpu") (define_insn_reservation "znver1_mmx_add" 1 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "type" "mmxadd") (eq_attr "memory" "none"))) "znver1-direct,znver1-fp0|znver1-fp1|znver1-fp3") (define_insn_reservation "znver1_mmx_add_load" 8 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "type" "mmxadd") (eq_attr "memory" "load"))) "znver1-direct,znver1-load,znver1-fp0|znver1-fp1|znver1-fp3") (define_insn_reservation "znver1_mmx_cmp" 1 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "type" "mmxcmp") (eq_attr "memory" "none"))) "znver1-direct,znver1-fp0|znver1-fp3") (define_insn_reservation "znver1_mmx_cmp_load" 8 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "type" "mmxcmp") (eq_attr "memory" "load"))) "znver1-direct,znver1-load,znver1-fp0|znver1-fp3") (define_insn_reservation "znver1_mmx_cvt_pck_shuf" 1 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "type" "mmxcvt,sseshuf,sseshuf1") (eq_attr "memory" "none"))) "znver1-direct,znver1-fp1|znver1-fp2") (define_insn_reservation "znver1_mmx_cvt_pck_shuf_load" 8 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "type" "mmxcvt,sseshuf,sseshuf1") (eq_attr "memory" "load"))) "znver1-direct,znver1-load,znver1-fp1|znver1-fp2") (define_insn_reservation "znver1_mmx_shift_move" 1 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "type" "mmxshft,mmxmov") (eq_attr "memory" "none"))) - "znver1-direct,znver1-fp2") + "znver1-direct,znver1-fp2") (define_insn_reservation "znver1_mmx_shift_move_load" 8 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "type" "mmxshft,mmxmov") (eq_attr "memory" "load"))) "znver1-direct,znver1-load,znver1-fp2") @@ -619,19 +671,19 @@ (eq_attr "memory" "store,both"))) "znver1-direct,znver1-fp2,znver1-store") (define_insn_reservation "znver2_mmx_move_store" 1 - (and (eq_attr "cpu" "znver1") + (and (eq_attr "cpu" "znver2,znver3") (and (eq_attr "type" "mmxshft,mmxmov") (eq_attr "memory" "store,both"))) "znver1-direct,znver1-fp2,znver2-store") (define_insn_reservation "znver1_mmx_mul" 3 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "type" "mmxmul") (eq_attr "memory" "none"))) "znver1-direct,znver1-fp0*3") (define_insn_reservation "znver1_mmx_load" 10 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "type" "mmxmul") (eq_attr "memory" "load"))) "znver1-direct,znver1-load,znver1-fp0*3") @@ -652,13 +704,13 @@ "znver1-double,znver1-load,znver1-fpu") (define_insn_reservation "znver1_sse_log" 1 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "type" "sselog") (eq_attr "memory" "none"))) "znver1-direct,znver1-fpu") (define_insn_reservation "znver1_sse_log_load" 8 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "type" "sselog") (eq_attr "memory" "load"))) "znver1-direct,znver1-load,znver1-fpu") @@ -678,13 +730,13 @@ "znver1-double,znver1-load,znver1-fp1|znver1-fp2") (define_insn_reservation "znver1_sse_log1" 1 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "type" "sselog1") (eq_attr "memory" "none"))) "znver1-direct,znver1-fp1|znver1-fp2") (define_insn_reservation "znver1_sse_log1_load" 8 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "type" "sselog1") (eq_attr "memory" "!none"))) "znver1-direct,znver1-load,znver1-fp1|znver1-fp2") @@ -701,7 +753,8 @@ (define_insn_reservation "znver1_sse_comi_load" 8 (and (ior (and (eq_attr "cpu" "znver1") (eq_attr "mode" "SF,DF,V4SF,V2DF")) - (eq_attr "cpu" "znver2")) + (ior (eq_attr "cpu" "znver2") + (eq_attr "cpu" "znver3"))) (and (eq_attr "prefix_extra" "0") (and (eq_attr "type" "ssecomi") (eq_attr "memory" "load")))) @@ -710,7 +763,8 @@ (define_insn_reservation "znver1_sse_comi_double" 2 (and (ior (and (eq_attr "cpu" "znver1") (eq_attr "mode" "V4SF,V2DF,TI")) - (eq_attr "cpu" "znver2")) + (ior (eq_attr "cpu" "znver2") + (eq_attr "cpu" "znver3"))) (and (eq_attr "prefix" "vex") (and (eq_attr "prefix_extra" "0") (and (eq_attr "type" "ssecomi") @@ -720,7 +774,8 @@ (define_insn_reservation "znver1_sse_comi_double_load" 10 (and (ior (and (eq_attr "cpu" "znver1") (eq_attr "mode" "V4SF,V2DF,TI")) - (eq_attr "cpu" "znver2")) + (ior (eq_attr "cpu" "znver2") + (eq_attr "cpu" "znver3"))) (and (eq_attr "prefix" "vex") (and (eq_attr "prefix_extra" "0") (and (eq_attr "type" "ssecomi") @@ -730,7 +785,8 @@ (define_insn_reservation "znver1_sse_test" 1 (and (ior (and (eq_attr "cpu" "znver1") (eq_attr "mode" "SF,DF,V4SF,V2DF,TI")) - (eq_attr "cpu" "znver2")) + (ior (eq_attr "cpu" "znver2") + (eq_attr "cpu" "znver3"))) (and (eq_attr "prefix_extra" "1") (and (eq_attr "type" "ssecomi") (eq_attr "memory" "none")))) @@ -739,7 +795,8 @@ (define_insn_reservation "znver1_sse_test_load" 8 (and (ior (and (eq_attr "cpu" "znver1") (eq_attr "mode" "SF,DF,V4SF,V2DF,TI")) - (eq_attr "cpu" "znver2")) + (ior (eq_attr "cpu" "znver2") + (eq_attr "cpu" "znver3"))) (and (eq_attr "prefix_extra" "1") (and (eq_attr "type" "ssecomi") (eq_attr "memory" "load")))) @@ -757,7 +814,7 @@ "znver1-direct,znver1-ieu0") (define_insn_reservation "znver2_sse_mov" 1 - (and (eq_attr "cpu" "znver2") + (and (eq_attr "cpu" "znver2,znver3") (and (eq_attr "mode" "SI") (and (eq_attr "isa" "avx") (and (eq_attr "type" "ssemov") @@ -774,7 +831,7 @@ "znver1-direct,znver1-ieu2") (define_insn_reservation "znver2_avx_mov" 1 - (and (eq_attr "cpu" "znver2") + (and (eq_attr "cpu" "znver2,znver3") (and (eq_attr "mode" "TI") (and (eq_attr "isa" "avx") (and (eq_attr "type" "ssemov") @@ -785,7 +842,8 @@ (define_insn_reservation "znver1_sseavx_mov" 1 (and (ior (and (eq_attr "cpu" "znver1") (eq_attr "mode" "SF,DF,V4SF,V2DF,TI")) - (eq_attr "cpu" "znver2")) + (ior (eq_attr "cpu" "znver2") + (eq_attr "cpu" "znver3"))) (and (eq_attr "type" "ssemov") (eq_attr "memory" "none"))) "znver1-direct,znver1-fpu") @@ -797,7 +855,7 @@ (eq_attr "memory" "store")))) "znver1-direct,znver1-fpu,znver1-store") (define_insn_reservation "znver2_sseavx_mov_store" 1 - (and (eq_attr "cpu" "znver2") + (and (eq_attr "cpu" "znver2,znver3") (and (eq_attr "type" "ssemov") (eq_attr "memory" "store"))) "znver1-direct,znver1-fpu,znver2-store") @@ -805,7 +863,8 @@ (define_insn_reservation "znver1_sseavx_mov_load" 8 (and (ior (and (eq_attr "cpu" "znver1") (eq_attr "mode" "SF,DF,V4SF,V2DF,TI")) - (eq_attr "cpu" "znver2")) + (ior (eq_attr "cpu" "znver2") + (eq_attr "cpu" "znver3"))) (and (eq_attr "type" "ssemov") (eq_attr "memory" "load"))) "znver1-direct,znver1-load,znver1-fpu") @@ -835,7 +894,8 @@ (define_insn_reservation "znver1_sseavx_add" 3 (and (ior (and (eq_attr "cpu" "znver1") (eq_attr "mode" "SF,DF,V4SF,V2DF,TI")) - (eq_attr "cpu" "znver2")) + (ior (eq_attr "cpu" "znver2") + (eq_attr "cpu" "znver3"))) (and (eq_attr "type" "sseadd") (eq_attr "memory" "none"))) "znver1-direct,znver1-fp2|znver1-fp3") @@ -843,7 +903,8 @@ (define_insn_reservation "znver1_sseavx_add_load" 10 (and (ior (and (eq_attr "cpu" "znver1") (eq_attr "mode" "SF,DF,V4SF,V2DF,TI")) - (eq_attr "cpu" "znver2")) + (ior (eq_attr "cpu" "znver2") + (eq_attr "cpu" "znver3"))) (and (eq_attr "type" "sseadd") (eq_attr "memory" "load"))) "znver1-direct,znver1-load,znver1-fp2|znver1-fp3") @@ -892,10 +953,39 @@ (eq_attr "memory" "load")))) "znver1-double,znver1-load,znver1-fp0|znver1-fp1") +(define_insn_reservation "znver3_sseavx_fma" 4 + (and (and (eq_attr "cpu" "znver3") + (eq_attr "mode" "SF,DF,V4SF,V2DF")) + (and (eq_attr "type" "ssemuladd") + (eq_attr "memory" "none"))) + "znver1-direct,znver1-fp0|znver1-fp1") + +(define_insn_reservation "znver3_sseavx_fma_load" 11 + (and (and (eq_attr "cpu" "znver3") + (eq_attr "mode" "SF,DF,V4SF,V2DF")) + (and (eq_attr "type" "ssemuladd") + (eq_attr "memory" "load"))) + "znver1-direct,znver1-load,znver1-fp0|znver1-fp1") + +(define_insn_reservation "znver3_avx256_fma" 4 + (and (eq_attr "cpu" "znver3") + (and (eq_attr "mode" "V8SF,V4DF") + (and (eq_attr "type" "ssemuladd") + (eq_attr "memory" "none")))) + "znver1-double,znver1-fp0|znver1-fp1") + +(define_insn_reservation "znver3_avx256_fma_load" 11 + (and (eq_attr "cpu" "znver3") + (and (eq_attr "mode" "V8SF,V4DF") + (and (eq_attr "type" "ssemuladd") + (eq_attr "memory" "load")))) + "znver1-double,znver1-load,znver1-fp0|znver1-fp1") + (define_insn_reservation "znver1_sseavx_iadd" 1 (and (ior (and (eq_attr "cpu" "znver1") (eq_attr "mode" "DI,TI")) - (eq_attr "cpu" "znver2")) + (ior (eq_attr "cpu" "znver2") + (eq_attr "cpu" "znver3"))) (and (eq_attr "type" "sseiadd") (eq_attr "memory" "none"))) "znver1-direct,znver1-fp0|znver1-fp1|znver1-fp3") @@ -903,7 +993,8 @@ (define_insn_reservation "znver1_sseavx_iadd_load" 8 (and (ior (and (eq_attr "cpu" "znver1") (eq_attr "mode" "DI,TI")) - (eq_attr "cpu" "znver2")) + (ior (eq_attr "cpu" "znver2") + (eq_attr "cpu" "znver3"))) (and (eq_attr "type" "sseiadd") (eq_attr "memory" "load"))) "znver1-direct,znver1-load,znver1-fp0|znver1-fp1|znver1-fp3") @@ -924,7 +1015,7 @@ ;; SSE conversions. (define_insn_reservation "znver1_ssecvtsf_si_load" 12 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "mode" "SI") (and (eq_attr "type" "sseicvt") (and (match_operand:SF 1 "memory_operand") @@ -939,7 +1030,7 @@ (eq_attr "memory" "none"))))) "znver1-double,znver1-fp3,znver1-ieu0") (define_insn_reservation "znver2_ssecvtdf_si" 4 - (and (eq_attr "cpu" "znver2") + (and (eq_attr "cpu" "znver2,znver3") (and (eq_attr "mode" "SI") (and (match_operand:DF 1 "register_operand") (and (eq_attr "type" "sseicvt") @@ -955,13 +1046,14 @@ "znver1-double,znver1-load,znver1-fp3,znver1-ieu0") (define_insn_reservation "znver2_ssecvtdf_si_load" 11 - (and (eq_attr "cpu" "znver2") + (and (eq_attr "cpu" "znver2,znver3") (and (eq_attr "mode" "SI") (and (eq_attr "type" "sseicvt") (and (match_operand:DF 1 "memory_operand") (eq_attr "memory" "load"))))) "znver1-double,znver1-load,znver1-fp3,znver1-ieu0") + ;; All other used ssecvt fp3 pipes ;; Check: Need to revisit this again. ;; Some SSE converts may use different pipe combinations. @@ -972,19 +1064,13 @@ "znver1-direct,znver1-fp3") (define_insn_reservation "znver2_ssecvt" 3 - (and (eq_attr "cpu" "znver2") + (and (eq_attr "cpu" "znver2,znver3") (and (eq_attr "type" "ssecvt") (eq_attr "memory" "none"))) "znver1-direct,znver1-fp3") (define_insn_reservation "znver1_ssecvt_load" 11 - (and (eq_attr "cpu" "znver1") - (and (eq_attr "type" "ssecvt") - (eq_attr "memory" "load"))) - "znver1-direct,znver1-load,znver1-fp3") - -(define_insn_reservation "znver2_ssecvt_load" 11 - (and (eq_attr "cpu" "znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "type" "ssecvt") (eq_attr "memory" "load"))) "znver1-direct,znver1-load,znver1-fp3") @@ -994,7 +1080,9 @@ (and (ior (and (eq_attr "cpu" "znver1") (eq_attr "mode" "V4SF,SF")) (and (eq_attr "cpu" "znver2") - (eq_attr "mode" "V8SF,V4SF,SF"))) + (eq_attr "mode" "V8SF,V4SF,SF")) + (and (eq_attr "cpu" "znver3") + (eq_attr "mode" "V8SF,V4SF,SF"))) (and (eq_attr "type" "ssediv") (eq_attr "memory" "none"))) "znver1-direct,znver1-fp3*10") @@ -1003,7 +1091,9 @@ (and (ior (and (eq_attr "cpu" "znver1") (eq_attr "mode" "V4SF,SF")) (and (eq_attr "cpu" "znver2") - (eq_attr "mode" "V8SF,V4SF,SF"))) + (eq_attr "mode" "V8SF,V4SF,SF")) + (and (eq_attr "cpu" "znver3") + (eq_attr "mode" "V8SF,V4SF,SF"))) (and (eq_attr "type" "ssediv") (eq_attr "memory" "load"))) "znver1-direct,znver1-load,znver1-fp3*10") @@ -1012,16 +1102,20 @@ (and (ior (and (eq_attr "cpu" "znver1") (eq_attr "mode" "V2DF,DF")) (and (eq_attr "cpu" "znver2") - (eq_attr "mode" "V4DF,V2DF,DF"))) + (eq_attr "mode" "V4DF,V2DF,DF")) + (and (eq_attr "cpu" "znver3") + (eq_attr "mode" "V4DF,V2DF,DF"))) (and (eq_attr "type" "ssediv") (eq_attr "memory" "none"))) "znver1-direct,znver1-fp3*13") (define_insn_reservation "znver1_ssediv_sd_pd_load" 20 (and (ior (and (eq_attr "cpu" "znver1") - (eq_attr "mode" "V2DF,DF")) + (eq_attr "mode" "V2DF,DF")) (and (eq_attr "cpu" "znver2") - (eq_attr "mode" "V4DF,V2DF,DF"))) + (eq_attr "mode" "V4DF,V2DF,DF")) + (and (eq_attr "cpu" "znver3") + (eq_attr "mode" "V4DF,V2DF,DF"))) (and (eq_attr "type" "ssediv") (eq_attr "memory" "load"))) "znver1-direct,znver1-load,znver1-fp3*13") @@ -1058,7 +1152,9 @@ (and (ior (and (eq_attr "cpu" "znver1") (eq_attr "mode" "V4SF,SF")) (and (eq_attr "cpu" "znver2") - (eq_attr "mode" "V8SF,V4SF,SF,V4DF,V2DF,DF"))) + (eq_attr "mode" "V8SF,V4SF,SF,V4DF,V2DF,DF")) + (and (eq_attr "cpu" "znver3") + (eq_attr "mode" "V8SF,V4SF,SF,V4DF,V2DF,DF"))) (and (eq_attr "type" "ssemul") (eq_attr "memory" "none"))) "znver1-direct,(znver1-fp0|znver1-fp1)*3") @@ -1067,7 +1163,9 @@ (and (ior (and (eq_attr "cpu" "znver1") (eq_attr "mode" "V4SF,SF")) (and (eq_attr "cpu" "znver2") - (eq_attr "mode" "V8SF,V4SF,SF"))) + (eq_attr "mode" "V8SF,V4SF,SF")) + (and (eq_attr "cpu" "znver3") + (eq_attr "mode" "V8SF,V4SF,SF"))) (and (eq_attr "type" "ssemul") (eq_attr "memory" "load"))) "znver1-direct,znver1-load,(znver1-fp0|znver1-fp1)*3") @@ -1101,17 +1199,18 @@ "znver1-direct,znver1-load,(znver1-fp0|znver1-fp1)*4") (define_insn_reservation "znver2_ssemul_sd_pd" 3 - (and (eq_attr "cpu" "znver2") + (and (eq_attr "cpu" "znver2,znver3") (and (eq_attr "type" "ssemul") (eq_attr "memory" "none"))) "znver1-direct,(znver1-fp0|znver1-fp1)*3") (define_insn_reservation "znver2_ssemul_sd_pd_load" 10 - (and (eq_attr "cpu" "znver2") + (and (eq_attr "cpu" "znver2,znver3") (and (eq_attr "type" "ssemul") (eq_attr "memory" "load"))) "znver1-direct,znver1-load,(znver1-fp0|znver1-fp1)*3") + (define_insn_reservation "znver1_ssemul_avx256_pd" 5 (and (eq_attr "cpu" "znver1") (and (eq_attr "mode" "V4DF") @@ -1131,13 +1230,15 @@ (and (ior (and (eq_attr "cpu" "znver1") (eq_attr "mode" "TI")) (and (eq_attr "cpu" "znver2") - (eq_attr "mode" "TI,OI"))) + (eq_attr "mode" "TI,OI")) + (and (eq_attr "cpu" "znver3") + (eq_attr "mode" "TI,OI"))) (and (eq_attr "type" "sseimul") (eq_attr "memory" "none"))) "znver1-direct,znver1-fp0*3") (define_insn_reservation "znver1_sseimul_avx256" 4 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "mode" "OI") (and (eq_attr "type" "sseimul") (eq_attr "memory" "none")))) @@ -1147,27 +1248,29 @@ (and (ior (and (eq_attr "cpu" "znver1") (eq_attr "mode" "TI")) (and (eq_attr "cpu" "znver2") + (eq_attr "mode" "TI,OI")) + (and (eq_attr "cpu" "znver3") (eq_attr "mode" "TI,OI"))) (and (eq_attr "type" "sseimul") (eq_attr "memory" "load"))) "znver1-direct,znver1-load,znver1-fp0*3") (define_insn_reservation "znver1_sseimul_avx256_load" 11 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "mode" "OI") (and (eq_attr "type" "sseimul") (eq_attr "memory" "load")))) "znver1-double,znver1-load,znver1-fp0*4") (define_insn_reservation "znver1_sseimul_di" 3 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "mode" "DI") (and (eq_attr "memory" "none") (eq_attr "type" "sseimul")))) "znver1-direct,znver1-fp0*3") (define_insn_reservation "znver1_sseimul_load_di" 10 - (and (eq_attr "cpu" "znver1,znver2") + (and (eq_attr "cpu" "znver1,znver2,znver3") (and (eq_attr "mode" "DI") (and (eq_attr "type" "sseimul") (eq_attr "memory" "load")))) @@ -1178,16 +1281,20 @@ (and (ior (and (eq_attr "cpu" "znver1") (eq_attr "mode" "SF,DF,V4SF,V2DF")) (and (eq_attr "cpu" "znver2") - (eq_attr "mode" "SF,DF,V4SF,V2DF,V8SF,V4DF"))) + (eq_attr "mode" "SF,DF,V4SF,V2DF,V8SF,V4DF")) + (and (eq_attr "cpu" "znver3") + (eq_attr "mode" "SF,DF,V4SF,V2DF,V8SF,V4DF"))) (and (eq_attr "type" "ssecmp") (eq_attr "memory" "none"))) "znver1-direct,znver1-fp0|znver1-fp1") (define_insn_reservation "znver1_sse_cmp_load" 8 (and (ior (and (eq_attr "cpu" "znver1") - (eq_attr "mode" "SF,DF,V4SF,V2DF")) + (eq_attr "mode" "SF,DF,V4SF,V2DF")) (and (eq_attr "cpu" "znver2") - (eq_attr "mode" "SF,DF,V4SF,V2DF,V8SF,V4DF"))) + (eq_attr "mode" "SF,DF,V4SF,V2DF,V8SF,V4DF")) + (and (eq_attr "cpu" "znver3") + (eq_attr "mode" "SF,DF,V4SF,V2DF,V8SF,V4DF"))) (and (eq_attr "type" "ssecmp") (eq_attr "memory" "load"))) "znver1-direct,znver1-load,znver1-fp0|znver1-fp1") @@ -1208,9 +1315,11 @@ (define_insn_reservation "znver1_sse_icmp" 1 (and (ior (and (eq_attr "cpu" "znver1") - (eq_attr "mode" "QI,HI,SI,DI,TI")) + (eq_attr "mode" "QI,HI,SI,DI,TI")) (and (eq_attr "cpu" "znver2") - (eq_attr "mode" "QI,HI,SI,DI,TI,OI"))) + (eq_attr "mode" "QI,HI,SI,DI,TI,OI")) + (and (eq_attr "cpu" "znver3") + (eq_attr "mode" "QI,HI,SI,DI,TI,OI"))) (and (eq_attr "type" "ssecmp") (eq_attr "memory" "none"))) "znver1-direct,znver1-fp0|znver1-fp3") @@ -1219,7 +1328,9 @@ (and (ior (and (eq_attr "cpu" "znver1") (eq_attr "mode" "QI,HI,SI,DI,TI")) (and (eq_attr "cpu" "znver2") - (eq_attr "mode" "QI,HI,SI,DI,TI,OI"))) + (eq_attr "mode" "QI,HI,SI,DI,TI,OI")) + (and (eq_attr "cpu" "znver3") + (eq_attr "mode" "QI,HI,SI,DI,TI,OI"))) (and (eq_attr "type" "ssecmp") (eq_attr "memory" "load"))) "znver1-direct,znver1-load,znver1-fp0|znver1-fp3") diff --git a/gcc/config/pdp11/pdp11.md b/gcc/config/pdp11/pdp11.md index 7a4d50f..cdef49f 100644 --- a/gcc/config/pdp11/pdp11.md +++ b/gcc/config/pdp11/pdp11.md @@ -105,7 +105,7 @@ (clobber (reg FCC_REGNUM))] "" [(set (reg:CC FCC_REGNUM) - (compare:CC (match_dup 1) (const_int 0))) + (compare:CC (match_dup 1) (const_double_zero))) (set (match_dup 0) (match_dup 1))]) (define_subst "fcc_ccnz" @@ -113,7 +113,7 @@ (clobber (reg FCC_REGNUM))] "" [(set (reg:CCNZ FCC_REGNUM) - (compare:CCNZ (match_dup 1) (const_int 0))) + (compare:CCNZ (match_dup 1) (const_double_zero))) (set (match_dup 0) (match_dup 1))]) (define_subst_attr "cc_cc" "cc_cc" "_nocc" "_cc") diff --git a/gcc/config/rs6000/xcoff.h b/gcc/config/rs6000/xcoff.h index 0f40b45..fe6221a 100644 --- a/gcc/config/rs6000/xcoff.h +++ b/gcc/config/rs6000/xcoff.h @@ -273,7 +273,9 @@ We still need to define this macro to let middle-end know that aliases are supported. */ -#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) do { } while (0) +#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) do { (void) (FILE); \ + (void) (LABEL1); \ + (void) (LABEL2); } while (0) /* Used by rs6000_assemble_integer, among others. */ diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index fb48102..2f83988 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -11082,7 +11082,7 @@ s390_prologue_plus_offset (rtx target, rtx reg, rtx offset, bool frame_related_p static void s390_emit_stack_probe (rtx addr) { - rtx mem = gen_rtx_MEM (Pmode, addr); + rtx mem = gen_rtx_MEM (word_mode, addr); MEM_VOLATILE_P (mem) = 1; emit_insn (gen_probe_stack (mem)); } diff --git a/gcc/config/vax/builtins.md b/gcc/config/vax/builtins.md index ac0e027..846d1f3 100644 --- a/gcc/config/vax/builtins.md +++ b/gcc/config/vax/builtins.md @@ -19,38 +19,151 @@ (define_constants [ - (VUNSPEC_LOCK 100) ; sync lock and test - (VUNSPEC_UNLOCK 101) ; sync lock release + (VUNSPEC_LOCK 100) ; sync lock operations ] ) -(define_expand "ffssi2" +(define_mode_attr width [(QI "8") (HI "16") (SI "32")]) +(define_mode_attr bb_mem [(QI "m") (HI "Q") (SI "Q")]) + +(define_int_iterator bit [0 1]) +(define_int_attr ccss [(0 "cc") (1 "ss")]) + +(define_code_iterator any_extend [sign_extend zero_extend]) + +(define_expand "ffs<mode>2" [(set (match_operand:SI 0 "nonimmediate_operand" "") - (ffs:SI (match_operand:SI 1 "general_operand" "")))] + (ffs:SI (match_operand:VAXint 1 "general_operand" "")))] "" " { rtx label = gen_label_rtx (); - emit_insn (gen_ffssi2_internal (operands[0], operands[1])); - emit_jump_insn (gen_bne (label)); - emit_insn (gen_negsi2 (operands[0], const1_rtx)); + rtx label_ref = gen_rtx_LABEL_REF (VOIDmode, label); + rtx cond = gen_rtx_NE (VOIDmode, operands[1], const0_rtx); + rtx target = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label_ref, pc_rtx); + + emit_insn (gen_ctz<mode>2_ccz (operands[0], operands[1])); + emit_jump_insn (gen_rtx_SET (pc_rtx, target)); + emit_insn (gen_neg<mode>2 (operands[0], const1_rtx)); emit_label (label); - emit_insn (gen_addsi3 (operands[0], operands[0], const1_rtx)); + emit_insn (gen_add<mode>3 (operands[0], operands[0], const1_rtx)); DONE; }") -(define_insn "ffssi2_internal" +(define_insn_and_split "ctz<mode>2" + [(set (match_operand:SI 0 "nonimmediate_operand" "=rQ") + (ctz:SI (match_operand:VAXint 1 "general_operand" "nrQT")))] + "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (ctz:SI (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*ctz<mode>2" + [(set (match_operand:SI 0 "nonimmediate_operand" "=rQ") + (ctz:SI (match_operand:VAXint 1 "general_operand" "nrQT"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" + "ffs $0,$<width>,%1,%0") + +(define_insn_and_split "ctz<mode>2_ccz" [(set (match_operand:SI 0 "nonimmediate_operand" "=rQ") - (ffs:SI (match_operand:SI 1 "general_operand" "nrQt"))) - (set (cc0) (match_dup 0))] + (ctz:SI (match_operand:VAXint 1 "general_operand" "nrQT")))] "" - "ffs $0,$32,%1,%0") + "#" + "reload_completed" + [(parallel + [(set (reg:CCZ VAX_PSL_REGNUM) + (compare:CCZ (match_dup 1) + (const_int 0))) + (set (match_dup 0) + (ctz:SI (match_dup 1)))])] + "") + +(define_insn "*ctz<mode>2_ccz" + [(set (reg:CCZ VAX_PSL_REGNUM) + (compare:CCZ (match_operand:VAXint 1 "general_operand" "nrQT") + (const_int 0))) + (set (match_operand:SI 0 "nonimmediate_operand" "=rQ") + (ctz:SI (match_dup 1)))] + "reload_completed" + "ffs $0,$<width>,%1,%0") + +;; Our FFS hardware instruction supports any field width, +;; so handle narrower inputs directly as well. +(define_peephole2 + [(parallel + [(set (match_operand:SI 0 "register_operand") + (any_extend:SI (match_operand:VAXintQH 1 "general_operand"))) + (clobber (reg:CC VAX_PSL_REGNUM))]) + (parallel + [(set (match_operand:SI 2 "nonimmediate_operand") + (ctz:SI (match_dup 0))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "rtx_equal_p (operands[0], operands[2]) || peep2_reg_dead_p (2, operands[0])" + [(parallel + [(set (match_dup 2) + (ctz:SI (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +;; The FFS hardware instruction sets the Z condition code based on +;; the input field rather than the output operand, so the compare +;; elimination pass cannot handle it. Try to get rid of the extra +;; operation by hand. +;; +;; The "ctz<mode>2_ccz" patterns require their `operands[1]' not to +;; have a mode dependent address, so all we need to verify is that +;; the two operands are not the same, in which case it's the FFS +;; output rather than input that condition codes are checked for. +(define_peephole2 + [(parallel + [(set (match_operand:SI 0 "nonimmediate_operand") + (ctz:SI (match_operand:VAXint 1 "general_operand"))) + (clobber (reg:CC VAX_PSL_REGNUM))]) + (set (reg:CCZ VAX_PSL_REGNUM) + (compare:CCZ (match_dup 1) + (const_int 0)))] + "!rtx_equal_p (operands[0], operands[1])" + [(parallel + [(set (reg:CCZ VAX_PSL_REGNUM) + (compare:CCZ (match_dup 1) + (const_int 0))) + (set (match_dup 0) + (ctz:SI (match_dup 1)))])] + "") + +;; This effectively combines the two peepholes above, +;; matching the sequence produced by `ffs<mode>2'. +(define_peephole2 + [(parallel + [(set (match_operand:SI 0 "register_operand") + (any_extend:SI (match_operand:VAXintQH 1 "general_operand"))) + (clobber (reg:CC VAX_PSL_REGNUM))]) + (parallel + [(set (match_operand:SI 2 "nonimmediate_operand") + (ctz:SI (match_dup 0))) + (clobber (reg:CC VAX_PSL_REGNUM))]) + (set (reg:CCZ VAX_PSL_REGNUM) + (compare:CCZ (match_dup 0) + (const_int 0)))] + "!rtx_equal_p (operands[0], operands[2]) + && peep2_reg_dead_p (3, operands[0])" + [(parallel + [(set (reg:CCZ VAX_PSL_REGNUM) + (compare:CCZ (match_dup 1) + (const_int 0))) + (set (match_dup 2) + (ctz:SI (match_dup 1)))])] + "") (define_expand "sync_lock_test_and_set<mode>" - [(set (match_operand:VAXint 0 "nonimmediate_operand" "=&g") - (unspec:VAXint [(match_operand:VAXint 1 "memory_operand" "+m") - (match_operand:VAXint 2 "const_int_operand" "n") - ] VUNSPEC_LOCK))] + [(match_operand:VAXint 0 "nonimmediate_operand" "=&g") + (match_operand:VAXint 1 "memory_operand" "+m") + (match_operand:VAXint 2 "const_int_operand" "n")] "" " { @@ -61,132 +174,46 @@ label = gen_label_rtx (); emit_move_insn (operands[0], const1_rtx); - emit_jump_insn (gen_jbbssi<mode> (operands[1], const0_rtx, label, operands[1])); + emit_jump_insn (gen_jbbssi<mode> (operands[1], const0_rtx, label, + operands[1])); emit_move_insn (operands[0], const0_rtx); emit_label (label); DONE; }") -(define_insn "jbbssiqi" - [(parallel - [(set (pc) - (if_then_else - (ne (zero_extract:SI (match_operand:QI 0 "memory_operand" "g") - (const_int 1) - (match_operand:SI 1 "general_operand" "nrm")) - (const_int 0)) - (label_ref (match_operand 2 "" "")) - (pc))) - (set (zero_extract:SI (match_operand:QI 3 "memory_operand" "+0") - (const_int 1) - (match_dup 1)) - (const_int 1))])] - "" - "jbssi %1,%0,%l2") - -(define_insn "jbbssihi" - [(parallel - [(set (pc) - (if_then_else - (ne (zero_extract:SI (match_operand:HI 0 "memory_operand" "Q") - (const_int 1) - (match_operand:SI 1 "general_operand" "nrm")) - (const_int 0)) - (label_ref (match_operand 2 "" "")) - (pc))) - (set (zero_extract:SI (match_operand:HI 3 "memory_operand" "+0") - (const_int 1) - (match_dup 1)) - (const_int 1))])] - "" - "jbssi %1,%0,%l2") - -(define_insn "jbbssisi" - [(parallel - [(set (pc) - (if_then_else - (ne (zero_extract:SI (match_operand:SI 0 "memory_operand" "Q") - (const_int 1) - (match_operand:SI 1 "general_operand" "nrm")) - (const_int 0)) - (label_ref (match_operand 2 "" "")) - (pc))) - (set (zero_extract:SI (match_operand:SI 3 "memory_operand" "+0") - (const_int 1) - (match_dup 1)) - (const_int 1))])] - "" - "jbssi %1,%0,%l2") - - (define_expand "sync_lock_release<mode>" - [(set (match_operand:VAXint 0 "memory_operand" "+m") - (unspec:VAXint [(match_operand:VAXint 1 "const_int_operand" "n") - ] VUNSPEC_UNLOCK))] + [(match_operand:VAXint 0 "memory_operand" "+m") + (match_operand:VAXint 1 "const_int_operand" "n")] "" " { rtx label; + if (operands[1] != const0_rtx) FAIL; -#if 1 + label = gen_label_rtx (); - emit_jump_insn (gen_jbbcci<mode> (operands[0], const0_rtx, label, operands[0])); + emit_jump_insn (gen_jbbcci<mode> (operands[0], const0_rtx, label, + operands[0])); emit_label (label); -#else - emit_move_insn (operands[0], const0_rtx); -#endif DONE; }") -(define_insn "jbbcciqi" - [(parallel - [(set (pc) - (if_then_else - (eq (zero_extract:SI (match_operand:QI 0 "memory_operand" "g") - (const_int 1) - (match_operand:SI 1 "general_operand" "nrm")) - (const_int 0)) - (label_ref (match_operand 2 "" "")) - (pc))) - (set (zero_extract:SI (match_operand:QI 3 "memory_operand" "+0") - (const_int 1) - (match_dup 1)) - (const_int 0))])] - "" - "jbcci %1,%0,%l2") - -(define_insn "jbbccihi" - [(parallel - [(set (pc) - (if_then_else - (eq (zero_extract:SI (match_operand:HI 0 "memory_operand" "Q") - (const_int 1) - (match_operand:SI 1 "general_operand" "nrm")) - (const_int 0)) - (label_ref (match_operand 2 "" "")) - (pc))) - (set (zero_extract:SI (match_operand:HI 3 "memory_operand" "+0") - (const_int 1) - (match_dup 1)) - (const_int 0))])] - "" - "jbcci %1,%0,%l2") - -(define_insn "jbbccisi" - [(parallel +(define_insn "jbb<ccss>i<mode>" + [(unspec_volatile [(set (pc) (if_then_else - (eq (zero_extract:SI (match_operand:SI 0 "memory_operand" "Q") - (const_int 1) - (match_operand:SI 1 "general_operand" "nrm")) - (const_int 0)) + (eq (zero_extract:SI + (match_operand:VAXint 0 "any_memory_operand" "<bb_mem>") + (const_int 1) + (match_operand:SI 1 "general_operand" "nrmT")) + (const_int bit)) (label_ref (match_operand 2 "" "")) (pc))) - (set (zero_extract:SI (match_operand:SI 3 "memory_operand" "+0") + (set (zero_extract:SI (match_operand:VAXint 3 "any_memory_operand" "+0") (const_int 1) (match_dup 1)) - (const_int 0))])] + (const_int bit))] + VUNSPEC_LOCK)] "" - "jbcci %1,%0,%l2") - + "jb<ccss>i %1,%0,%l2") diff --git a/gcc/config/vax/constraints.md b/gcc/config/vax/constraints.md index b8262b6..d4eddb8 100644 --- a/gcc/config/vax/constraints.md +++ b/gcc/config/vax/constraints.md @@ -112,6 +112,10 @@ (and (match_operand:DI 0 "memory_operand") (not (match_operand:DI 0 "illegal_addsub_di_memory_operand" "")))) +(define_constraint "A" + "@internal An integer constant suitable for address load operations." + (match_test ("CONSTANT_P (op) && pic_symbolic_operand (op, mode)"))) + (define_constraint "T" "@internal satisfies CONSTANT_P and, if pic is enabled, is not a SYMBOL_REF, LABEL_REF, or CONST." (and (match_test ("CONSTANT_P (op)")) diff --git a/gcc/config/vax/elf.h b/gcc/config/vax/elf.h index 555ccef..f6485eca 100644 --- a/gcc/config/vax/elf.h +++ b/gcc/config/vax/elf.h @@ -26,7 +26,8 @@ along with GCC; see the file COPYING3. If not see #define REGISTER_PREFIX "%" #define REGISTER_NAMES \ { "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7", \ - "%r8", "%r9", "%r10", "%r11", "%ap", "%fp", "%sp", "%pc", } + "%r8", "%r9", "%r10", "%r11", "%ap", "%fp", "%sp", "%pc", \ + "%psl" } #undef SIZE_TYPE #define SIZE_TYPE "long unsigned int" @@ -89,6 +90,16 @@ along with GCC; see the file COPYING3. If not see %{!fpic: \ %{!fPIC:-fPIC}}}" +/* Don't let the LTO compiler switch the PIC options off. */ +#define VAX_CC1_SPEC \ + VAX_CC1_AND_CC1PLUS_SPEC \ + " %{flinker-output=exec" \ + ":%{no-pie:-flinker-output=exec;:-flinker-output=pie};" \ + ":%{flinker-output=*}}" \ + "%<flinker-output*" +#define VAX_CC1PLUS_SPEC \ + VAX_CC1_AND_CC1PLUS_SPEC + /* VAX ELF is always gas; override the generic VAX ASM_SPEC. */ #undef ASM_SPEC diff --git a/gcc/config/vax/netbsd-elf.h b/gcc/config/vax/netbsd-elf.h index 26b98ef..9a01fdd 100644 --- a/gcc/config/vax/netbsd-elf.h +++ b/gcc/config/vax/netbsd-elf.h @@ -35,10 +35,10 @@ along with GCC; see the file COPYING3. If not see #endif #undef CC1_SPEC -#define CC1_SPEC NETBSD_CC1_AND_CC1PLUS_SPEC VAX_CC1_AND_CC1PLUS_SPEC +#define CC1_SPEC NETBSD_CC1_AND_CC1PLUS_SPEC VAX_CC1_SPEC #undef CC1PLUS_SPEC -#define CC1PLUS_SPEC NETBSD_CC1_AND_CC1PLUS_SPEC VAX_CC1_AND_CC1PLUS_SPEC +#define CC1PLUS_SPEC NETBSD_CC1_AND_CC1PLUS_SPEC VAX_CC1PLUS_SPEC #define NETBSD_ENTRY_POINT "__start" diff --git a/gcc/config/vax/predicates.md b/gcc/config/vax/predicates.md index 7eefc60..92caf83 100644 --- a/gcc/config/vax/predicates.md +++ b/gcc/config/vax/predicates.md @@ -17,39 +17,27 @@ ;; along with GCC; see the file COPYING3. If not see ;; <http://www.gnu.org/licenses/>. +;; Return true if OP is a constant zero operand. +(define_predicate "const_zero_operand" + (match_test "op == CONST0_RTX (mode)")) + ;; Special case of a symbolic operand that's used as a ;; operand. (define_predicate "symbolic_operand" (match_code "const,symbol_ref,label_ref")) -(define_predicate "local_symbolic_operand" - (match_code "const,symbol_ref,label_ref") -{ - if (GET_CODE (op) == LABEL_REF) - return 1; - if (GET_CODE (op) == SYMBOL_REF) - return !flag_pic || SYMBOL_REF_LOCAL_P (op); - if (GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF) - return 1; - return !flag_pic || SYMBOL_REF_LOCAL_P (XEXP (XEXP (op, 0), 0)); -}) - -(define_predicate "external_symbolic_operand" - (and (match_code "symbol_ref") - (not (match_operand 0 "local_symbolic_operand" "")))) - -(define_predicate "external_const_operand" - (and (match_code "const") - (match_test "GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF - && !SYMBOL_REF_LOCAL_P (XEXP (XEXP (op, 0), 0))"))) +(define_predicate "pic_symbolic_operand" + (and (match_code "const,symbol_ref,label_ref") + (match_test "!flag_pic + || vax_acceptable_pic_operand_p (op, false, true)"))) (define_predicate "nonsymbolic_operand" (and (ior (match_test "!flag_pic") (not (match_operand 0 "symbolic_operand"))) (match_operand 0 "general_operand" ""))) -(define_predicate "external_memory_operand" +(define_predicate "non_pic_external_memory_operand" (match_code "mem") { rtx addr = XEXP (op, 0); @@ -61,8 +49,8 @@ addr = XEXP (addr, 0); if (GET_CODE (addr) == PLUS) addr = XEXP (addr, 1); - return external_symbolic_operand (addr, SImode) - || external_const_operand (addr, SImode); + return (symbolic_operand (addr, SImode) + && !vax_acceptable_pic_operand_p (addr, true, true)); }) (define_predicate "indirect_memory_operand" @@ -87,7 +75,7 @@ (define_predicate "illegal_blk_memory_operand" (and (match_code "mem") (ior (and (match_test "flag_pic") - (match_operand 0 "external_memory_operand" "")) + (match_operand 0 "non_pic_external_memory_operand" "")) (ior (match_operand 0 "indexed_memory_operand" "") (ior (match_operand 0 "indirect_memory_operand" "") (match_test "GET_CODE (XEXP (op, 0)) == PRE_DEC")))))) @@ -95,7 +83,7 @@ (define_predicate "illegal_addsub_di_memory_operand" (and (match_code "mem") (ior (and (match_test "flag_pic") - (match_operand 0 "external_memory_operand" "")) + (match_operand 0 "non_pic_external_memory_operand" "")) (ior (match_operand 0 "indexed_memory_operand" "") (ior (match_operand 0 "indirect_memory_operand" "") (match_test "GET_CODE (XEXP (op, 0)) == PRE_DEC")))))) @@ -109,3 +97,35 @@ (and (match_code "const_int,const_double,subreg,reg,mem") (and (match_operand:DI 0 "general_operand" "") (not (match_operand:DI 0 "illegal_addsub_di_memory_operand"))))) + +;; Return 1 if the operand is in volatile memory. Note that during the +;; RTL generation phase, `memory_operand' does not return TRUE for +;; volatile memory references. So this function allows us to recognize +;; volatile references where it's safe. +(define_predicate "volatile_mem_operand" + (and (match_code "mem") + (match_test "MEM_VOLATILE_P (op)") + (if_then_else (match_test "reload_completed") + (match_operand 0 "memory_operand") + (match_test "memory_address_p (mode, XEXP (op, 0))")))) + +;; Return 1 if the operand is a volatile or non-volatile memory operand. +(define_predicate "any_memory_operand" + (ior (match_operand 0 "memory_operand") + (match_operand 0 "volatile_mem_operand"))) + +;; Return true if OP is a comparison operator that requires at least CCmode. +(define_predicate "vax_cc_comparison_operator" + (match_code "geu,gtu,leu,ltu")) + +;; Return true if OP is a comparison operator that requires at least CCNmode. +(define_predicate "vax_ccn_comparison_operator" + (match_code "ge,lt")) + +;; Return true if OP is a comparison operator that requires at least CCNZmode. +(define_predicate "vax_ccnz_comparison_operator" + (match_code "gt,le")) + +;; Return true if OP is a comparison operator that requires at least CCZmode. +(define_predicate "vax_ccz_comparison_operator" + (match_code "ne,eq")) diff --git a/gcc/config/vax/vax-modes.def b/gcc/config/vax/vax-modes.def index 5f1c994..2a7438e 100644 --- a/gcc/config/vax/vax-modes.def +++ b/gcc/config/vax/vax-modes.def @@ -20,3 +20,14 @@ along with GCC; see the file COPYING3. If not see /* We just need to reset the floating point formats. */ RESET_FLOAT_FORMAT (SF, vax_f_format); RESET_FLOAT_FORMAT (DF, vax_d_format); + +/* `DImode' addition and subtraction operations do their calculation + on the low and then the high longword with separate instructions, + and therefore only usably set N. */ +CC_MODE (CCN); +/* Non-arithmetic integer instructions such as MOV or XOR as well as + instructions that produce a floating-point result only usably set + N and Z. */ +CC_MODE (CCNZ); +/* The FFC and FFS instructions only usably set Z. */ +CC_MODE (CCZ); diff --git a/gcc/config/vax/vax-protos.h b/gcc/config/vax/vax-protos.h index cda2544..aa949c5 100644 --- a/gcc/config/vax/vax-protos.h +++ b/gcc/config/vax/vax-protos.h @@ -21,13 +21,15 @@ extern bool legitimate_constant_address_p (rtx); extern void vax_expand_prologue (void); #ifdef RTX_CODE +extern bool vax_acceptable_pic_operand_p (rtx, bool, bool); +extern machine_mode vax_select_cc_mode (enum rtx_code, rtx, rtx); extern const char *cond_name (rtx); extern bool adjacent_operands_p (rtx, rtx, machine_mode); extern const char *rev_cond_name (rtx); extern void print_operand_address (FILE *, rtx); extern void print_operand (FILE *, rtx, int); -extern void vax_notice_update_cc (rtx, rtx); extern void vax_expand_addsub_di_operands (rtx *, enum rtx_code); +extern bool vax_maybe_split_dimode_move (rtx *); extern const char * vax_output_int_move (rtx, rtx *, machine_mode); extern const char * vax_output_int_add (rtx_insn *, rtx *, machine_mode); extern const char * vax_output_int_subtract (rtx_insn *, rtx *, machine_mode); diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c index da4e6cb..54d83dc 100644 --- a/gcc/config/vax/vax.c +++ b/gcc/config/vax/vax.c @@ -54,6 +54,10 @@ static void vax_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, static int vax_address_cost_1 (rtx); static int vax_address_cost (rtx, machine_mode, addr_space_t, bool); static bool vax_rtx_costs (rtx, machine_mode, int, int, int *, bool); +static machine_mode vax_cc_modes_compatible (machine_mode, machine_mode); +static rtx_insn *vax_md_asm_adjust (vec<rtx> &, vec<rtx> &, + vec<const char *> &, + vec<rtx> &, HARD_REG_SET &); static rtx vax_function_arg (cumulative_args_t, const function_arg_info &); static void vax_function_arg_advance (cumulative_args_t, const function_arg_info &); @@ -81,11 +85,23 @@ static HOST_WIDE_INT vax_starting_frame_offset (void); #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall +/* Enable compare elimination pass. */ +#undef TARGET_FLAGS_REGNUM +#define TARGET_FLAGS_REGNUM VAX_PSL_REGNUM + #undef TARGET_RTX_COSTS #define TARGET_RTX_COSTS vax_rtx_costs #undef TARGET_ADDRESS_COST #define TARGET_ADDRESS_COST vax_address_cost +/* Return the narrowest CC mode that spans both modes offered. */ +#undef TARGET_CC_MODES_COMPATIBLE +#define TARGET_CC_MODES_COMPATIBLE vax_cc_modes_compatible + +/* Mark PSL as clobbered for compatibility with the CC0 representation. */ +#undef TARGET_MD_ASM_ADJUST +#define TARGET_MD_ASM_ADJUST vax_md_asm_adjust + #undef TARGET_PROMOTE_PROTOTYPES #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true @@ -509,9 +525,9 @@ print_operand (FILE *file, rtx x, int code) fputc (ASM_DOUBLE_CHAR, file); else if (code == '|') fputs (REGISTER_PREFIX, file); - else if (code == 'c') + else if (code == 'k') fputs (cond_name (x), file); - else if (code == 'C') + else if (code == 'K') fputs (rev_cond_name (x), file); else if (code == 'D' && CONST_INT_P (x) && INTVAL (x) < 0) fprintf (file, "$" NEG_HWI_PRINT_HEX16, INTVAL (x)); @@ -748,7 +764,7 @@ vax_address_cost (rtx x, machine_mode mode ATTRIBUTE_UNUSED, addr_space_t as ATTRIBUTE_UNUSED, bool speed ATTRIBUTE_UNUSED) { - return (1 + (REG_P (x) ? 0 : vax_address_cost_1 (x))); + return COSTS_N_INSNS (1 + (REG_P (x) ? 0 : vax_address_cost_1 (x))); } /* Cost of an expression on a VAX. This version has costs tuned for the @@ -778,12 +794,13 @@ vax_rtx_costs (rtx x, machine_mode mode, int outer_code, case CONST_INT: if (INTVAL (x) == 0) { - *total = 0; + *total = COSTS_N_INSNS (1) / 2; return true; } if (outer_code == AND) { - *total = ((unsigned HOST_WIDE_INT) ~INTVAL (x) <= 077) ? 1 : 2; + *total = ((unsigned HOST_WIDE_INT) ~INTVAL (x) <= 077 + ? COSTS_N_INSNS (1) : COSTS_N_INSNS (2)); return true; } if ((unsigned HOST_WIDE_INT) INTVAL (x) <= 077 @@ -792,7 +809,7 @@ vax_rtx_costs (rtx x, machine_mode mode, int outer_code, || ((outer_code == PLUS || outer_code == MINUS) && (unsigned HOST_WIDE_INT) -INTVAL (x) <= 077)) { - *total = 1; + *total = COSTS_N_INSNS (1); return true; } /* FALLTHRU */ @@ -800,48 +817,48 @@ vax_rtx_costs (rtx x, machine_mode mode, int outer_code, case CONST: case LABEL_REF: case SYMBOL_REF: - *total = 3; + *total = COSTS_N_INSNS (3); return true; case CONST_DOUBLE: if (GET_MODE_CLASS (mode) == MODE_FLOAT) - *total = vax_float_literal (x) ? 5 : 8; + *total = vax_float_literal (x) ? COSTS_N_INSNS (5) : COSTS_N_INSNS (8); else *total = ((CONST_DOUBLE_HIGH (x) == 0 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x) < 64) || (outer_code == PLUS && CONST_DOUBLE_HIGH (x) == -1 - && (unsigned HOST_WIDE_INT)-CONST_DOUBLE_LOW (x) < 64)) - ? 2 : 5; + && (unsigned HOST_WIDE_INT)-CONST_DOUBLE_LOW (x) < 64) + ? COSTS_N_INSNS (2) : COSTS_N_INSNS (5)); return true; case POST_INC: - *total = 2; - return true; /* Implies register operand. */ + *total = COSTS_N_INSNS (2); + return true; /* Implies register operand. */ case PRE_DEC: - *total = 3; - return true; /* Implies register operand. */ + *total = COSTS_N_INSNS (3); + return true; /* Implies register operand. */ case MULT: switch (mode) { case E_DFmode: - *total = 16; /* 4 on VAX 9000 */ + *total = COSTS_N_INSNS (16); /* 4 on VAX 9000 */ break; case E_SFmode: - *total = 9; /* 4 on VAX 9000, 12 on VAX 2 */ + *total = COSTS_N_INSNS (9); /* 4 on VAX 9000, 12 on VAX 2 */ break; case E_DImode: - *total = 16; /* 6 on VAX 9000, 28 on VAX 2 */ + *total = COSTS_N_INSNS (16); /* 6 on VAX 9000, 28 on VAX 2 */ break; case E_SImode: case E_HImode: case E_QImode: - *total = 10; /* 3-4 on VAX 9000, 20-28 on VAX 2 */ + *total = COSTS_N_INSNS (10); /* 3-4 on VAX 9000, 20-28 on VAX 2 */ break; default: - *total = MAX_COST; /* Mode is not supported. */ + *total = MAX_COST; /* Mode is not supported. */ return true; } break; @@ -849,63 +866,65 @@ vax_rtx_costs (rtx x, machine_mode mode, int outer_code, case UDIV: if (mode != SImode) { - *total = MAX_COST; /* Mode is not supported. */ + *total = MAX_COST; /* Mode is not supported. */ return true; } - *total = 17; + *total = COSTS_N_INSNS (17); break; case DIV: if (mode == DImode) - *total = 30; /* Highly variable. */ + *total = COSTS_N_INSNS (30); /* Highly variable. */ else if (mode == DFmode) /* divide takes 28 cycles if the result is not zero, 13 otherwise */ - *total = 24; + *total = COSTS_N_INSNS (24); else - *total = 11; /* 25 on VAX 2 */ + *total = COSTS_N_INSNS (11); /* 25 on VAX 2 */ break; case MOD: - *total = 23; + *total = COSTS_N_INSNS (23); break; case UMOD: if (mode != SImode) { - *total = MAX_COST; /* Mode is not supported. */ + *total = MAX_COST; /* Mode is not supported. */ return true; } - *total = 29; + *total = COSTS_N_INSNS (29); break; case FLOAT: - *total = (6 /* 4 on VAX 9000 */ - + (mode == DFmode) + (GET_MODE (XEXP (x, 0)) != SImode)); + *total = COSTS_N_INSNS (6 /* 4 on VAX 9000 */ + + (mode == DFmode) + + (GET_MODE (XEXP (x, 0)) != SImode)); break; case FIX: - *total = 7; /* 17 on VAX 2 */ + *total = COSTS_N_INSNS (7); /* 17 on VAX 2 */ break; case ASHIFT: case LSHIFTRT: case ASHIFTRT: if (mode == DImode) - *total = 12; + *total = COSTS_N_INSNS (12); else - *total = 10; /* 6 on VAX 9000 */ + *total = COSTS_N_INSNS (10); /* 6 on VAX 9000 */ break; case ROTATE: case ROTATERT: - *total = 6; /* 5 on VAX 2, 4 on VAX 9000 */ + *total = COSTS_N_INSNS (6); /* 5 on VAX 2, 4 on VAX 9000 */ if (CONST_INT_P (XEXP (x, 1))) fmt = "e"; /* all constant rotate counts are short */ break; case PLUS: case MINUS: - *total = (mode == DFmode) ? 13 : 8; /* 6/8 on VAX 9000, 16/15 on VAX 2 */ + *total = (mode == DFmode /* 6/8 on VAX 9000, 16/15 on VAX 2 */ + ? COSTS_N_INSNS (13) : COSTS_N_INSNS (8)); /* Small integer operands can use subl2 and addl2. */ if ((CONST_INT_P (XEXP (x, 1))) && (unsigned HOST_WIDE_INT)(INTVAL (XEXP (x, 1)) + 63) < 127) @@ -914,16 +933,16 @@ vax_rtx_costs (rtx x, machine_mode mode, int outer_code, case IOR: case XOR: - *total = 3; + *total = COSTS_N_INSNS (3); break; case AND: /* AND is special because the first operand is complemented. */ - *total = 3; + *total = COSTS_N_INSNS (3); if (CONST_INT_P (XEXP (x, 0))) { if ((unsigned HOST_WIDE_INT)~INTVAL (XEXP (x, 0)) > 63) - *total = 4; + *total = COSTS_N_INSNS (4); fmt = "e"; i = 1; } @@ -931,38 +950,38 @@ vax_rtx_costs (rtx x, machine_mode mode, int outer_code, case NEG: if (mode == DFmode) - *total = 9; + *total = COSTS_N_INSNS (9); else if (mode == SFmode) - *total = 6; + *total = COSTS_N_INSNS (6); else if (mode == DImode) - *total = 4; + *total = COSTS_N_INSNS (4); else - *total = 2; + *total = COSTS_N_INSNS (2); break; case NOT: - *total = 2; + *total = COSTS_N_INSNS (2); break; case ZERO_EXTRACT: case SIGN_EXTRACT: - *total = 15; + *total = COSTS_N_INSNS (15); break; case MEM: if (mode == DImode || mode == DFmode) - *total = 5; /* 7 on VAX 2 */ + *total = COSTS_N_INSNS (5); /* 7 on VAX 2 */ else - *total = 3; /* 4 on VAX 2 */ + *total = COSTS_N_INSNS (3); /* 4 on VAX 2 */ x = XEXP (x, 0); if (!REG_P (x) && GET_CODE (x) != POST_INC) - *total += vax_address_cost_1 (x); + *total += COSTS_N_INSNS (vax_address_cost_1 (x)); return true; case FLOAT_EXTEND: case FLOAT_TRUNCATE: case TRUNCATE: - *total = 3; /* FIXME: Costs need to be checked */ + *total = COSTS_N_INSNS (3); /* FIXME: Costs need to be checked */ break; default: @@ -993,12 +1012,12 @@ vax_rtx_costs (rtx x, machine_mode mode, int outer_code, case CONST_INT: if ((unsigned HOST_WIDE_INT)INTVAL (op) > 63 && mode != QImode) - *total += 1; /* 2 on VAX 2 */ + *total += COSTS_N_INSNS (1); /* 2 on VAX 2 */ break; case CONST: case LABEL_REF: case SYMBOL_REF: - *total += 1; /* 2 on VAX 2 */ + *total += COSTS_N_INSNS (1); /* 2 on VAX 2 */ break; case CONST_DOUBLE: if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT) @@ -1006,33 +1025,163 @@ vax_rtx_costs (rtx x, machine_mode mode, int outer_code, /* Registers are faster than floating point constants -- even those constants which can be encoded in a single byte. */ if (vax_float_literal (op)) - *total += 1; + *total += COSTS_N_INSNS (1); else - *total += (GET_MODE (x) == DFmode) ? 3 : 2; + *total += (GET_MODE (x) == DFmode + ? COSTS_N_INSNS (3) : COSTS_N_INSNS (2)); } else { if (CONST_DOUBLE_HIGH (op) != 0 || (unsigned HOST_WIDE_INT)CONST_DOUBLE_LOW (op) > 63) - *total += 2; + *total += COSTS_N_INSNS (2); } break; case MEM: - *total += 1; /* 2 on VAX 2 */ + *total += COSTS_N_INSNS (1); /* 2 on VAX 2 */ if (!REG_P (XEXP (op, 0))) - *total += vax_address_cost_1 (XEXP (op, 0)); + *total += COSTS_N_INSNS (vax_address_cost_1 (XEXP (op, 0))); break; case REG: case SUBREG: break; default: - *total += 1; + *total += COSTS_N_INSNS (1); break; } } return true; } +/* With ELF we do not support GOT entries for external `symbol+offset' + references, so do not accept external symbol references if an offset + is to be added. Do not accept external symbol references at all if + LOCAL_P is set. This is for cases where making a reference indirect + would make it invalid. Do not accept any kind of symbols if SYMBOL_P + is clear. This is for situations where the a reference is used as an + immediate value for operations other than address loads (MOVA/PUSHA), + as those operations do not support PC-relative immediates. */ + +bool +vax_acceptable_pic_operand_p (rtx x ATTRIBUTE_UNUSED, + bool local_p ATTRIBUTE_UNUSED, + bool symbol_p ATTRIBUTE_UNUSED) +{ +#ifdef NO_EXTERNAL_INDIRECT_ADDRESS + if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS) + { + x = XEXP (XEXP (x, 0), 0); + local_p = true; + } + switch (GET_CODE (x)) + { + case SYMBOL_REF: + return symbol_p && !(local_p && !SYMBOL_REF_LOCAL_P (x)); + case LABEL_REF: + return symbol_p && !(local_p && LABEL_REF_NONLOCAL_P (x)); + default: + break; + } +#endif + return true; +} + +/* Given a comparison code (NE, EQ, etc.) and the operands of a COMPARE, + return the mode to be used for the comparison. As we have the same + interpretation of condition codes across all the instructions we just + return the narrowest mode suitable for the comparison code requested. */ + +extern machine_mode +vax_select_cc_mode (enum rtx_code op, + rtx x ATTRIBUTE_UNUSED, rtx y ATTRIBUTE_UNUSED) +{ + switch (op) + { + default: + gcc_unreachable (); + case NE: + case EQ: + return CCZmode; + case GE: + case LT: + return CCNmode; + case GT: + case LE: + return CCNZmode; + case GEU: + case GTU: + case LEU: + case LTU: + return CCmode; + } +} + +/* Return the narrowest CC mode that spans both modes offered. If they + intersect, this will be the wider of the two, and if they do not then + find find one that is a superset of both (i.e. CCNZmode for a pair + consisting of CCNmode and CCZmode). A wider CC writer will satisfy + a narrower CC reader, e.g. a comparison operator that uses CCZmode + can use a CCNZmode output of a previous instruction. */ + +static machine_mode +vax_cc_modes_compatible (machine_mode m1, machine_mode m2) +{ + switch (m1) + { + default: + gcc_unreachable (); + case E_CCmode: + switch (m2) + { + default: + gcc_unreachable (); + case E_CCmode: + case E_CCNZmode: + case E_CCNmode: + case E_CCZmode: + return m1; + } + case E_CCNZmode: + switch (m2) + { + default: + gcc_unreachable (); + case E_CCmode: + return m2; + case E_CCNmode: + case E_CCNZmode: + case E_CCZmode: + return m1; + } + case E_CCNmode: + case E_CCZmode: + switch (m2) + { + default: + gcc_unreachable (); + case E_CCmode: + case E_CCNZmode: + return m2; + case E_CCNmode: + case E_CCZmode: + return m1 == m2 ? m1 : E_CCNZmode; + } + } +} + +/* Mark PSL as clobbered for compatibility with the CC0 representation. */ + +static rtx_insn * +vax_md_asm_adjust (vec<rtx> &outputs ATTRIBUTE_UNUSED, + vec<rtx> &inputs ATTRIBUTE_UNUSED, + vec<const char *> &constraints ATTRIBUTE_UNUSED, + vec<rtx> &clobbers, HARD_REG_SET &clobbered_regs) +{ + clobbers.safe_push (gen_rtx_REG (CCmode, VAX_PSL_REGNUM)); + SET_HARD_REG_BIT (clobbered_regs, VAX_PSL_REGNUM); + return NULL; +} + /* Output code to add DELTA to the first argument, and then jump to FUNCTION. Used for C++ multiple inheritance. .mask ^m<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11> #conservative entry mask @@ -1065,78 +1214,21 @@ vax_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED, return gen_rtx_REG (Pmode, VAX_STRUCT_VALUE_REGNUM); } -/* Worker function for NOTICE_UPDATE_CC. */ +/* Output integer move instructions. */ -void -vax_notice_update_cc (rtx exp, rtx insn ATTRIBUTE_UNUSED) +bool +vax_maybe_split_dimode_move (rtx *operands) { - if (GET_CODE (exp) == SET) - { - if (GET_CODE (SET_SRC (exp)) == CALL) - CC_STATUS_INIT; - else if (GET_CODE (SET_DEST (exp)) != ZERO_EXTRACT - && GET_CODE (SET_DEST (exp)) != PC) - { - cc_status.flags = 0; - /* The integer operations below don't set carry or - set it in an incompatible way. That's ok though - as the Z bit is all we need when doing unsigned - comparisons on the result of these insns (since - they're always with 0). Set CC_NO_OVERFLOW to - generate the correct unsigned branches. */ - switch (GET_CODE (SET_SRC (exp))) - { - case NEG: - if (GET_MODE_CLASS (GET_MODE (exp)) == MODE_FLOAT) - break; - /* FALLTHRU */ - case AND: - case IOR: - case XOR: - case NOT: - case MEM: - case REG: - cc_status.flags = CC_NO_OVERFLOW; - break; - default: - break; - } - cc_status.value1 = SET_DEST (exp); - cc_status.value2 = SET_SRC (exp); - } - } - else if (GET_CODE (exp) == PARALLEL - && GET_CODE (XVECEXP (exp, 0, 0)) == SET) - { - if (GET_CODE (SET_SRC (XVECEXP (exp, 0, 0))) == CALL) - CC_STATUS_INIT; - else if (GET_CODE (SET_DEST (XVECEXP (exp, 0, 0))) != PC) - { - cc_status.flags = 0; - cc_status.value1 = SET_DEST (XVECEXP (exp, 0, 0)); - cc_status.value2 = SET_SRC (XVECEXP (exp, 0, 0)); - } - else - /* PARALLELs whose first element sets the PC are aob, - sob insns. They do change the cc's. */ - CC_STATUS_INIT; - } - else - CC_STATUS_INIT; - if (cc_status.value1 && REG_P (cc_status.value1) - && cc_status.value2 - && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2)) - cc_status.value2 = 0; - if (cc_status.value1 && MEM_P (cc_status.value1) - && cc_status.value2 - && MEM_P (cc_status.value2)) - cc_status.value2 = 0; - /* Actual condition, one line up, should be that value2's address - depends on value1, but that is too much of a pain. */ + return (TARGET_QMATH + && (!MEM_P (operands[0]) + || GET_CODE (XEXP (operands[0], 0)) == PRE_DEC + || GET_CODE (XEXP (operands[0], 0)) == POST_INC + || !illegal_addsub_di_memory_operand (operands[0], DImode)) + && ((CONST_INT_P (operands[1]) + && (unsigned HOST_WIDE_INT) INTVAL (operands[1]) >= 64) + || GET_CODE (operands[1]) == CONST_DOUBLE)); } -/* Output integer move instructions. */ - const char * vax_output_int_move (rtx insn ATTRIBUTE_UNUSED, rtx *operands, machine_mode mode) @@ -1212,14 +1304,7 @@ vax_output_int_move (rtx insn ATTRIBUTE_UNUSED, rtx *operands, } } - if (TARGET_QMATH - && (!MEM_P (operands[0]) - || GET_CODE (XEXP (operands[0], 0)) == PRE_DEC - || GET_CODE (XEXP (operands[0], 0)) == POST_INC - || !illegal_addsub_di_memory_operand (operands[0], DImode)) - && ((CONST_INT_P (operands[1]) - && (unsigned HOST_WIDE_INT) INTVAL (operands[1]) >= 64) - || GET_CODE (operands[1]) == CONST_DOUBLE)) + if (vax_maybe_split_dimode_move (operands)) { hi[0] = operands[0]; hi[1] = operands[1]; @@ -1370,8 +1455,10 @@ vax_output_int_add (rtx_insn *insn, rtx *operands, machine_mode mode) { gcc_assert (rtx_equal_p (operands[0], operands[1])); #ifdef NO_EXTERNAL_INDIRECT_ADDRESS - gcc_assert (!flag_pic || !external_memory_operand (low[2], SImode)); - gcc_assert (!flag_pic || !external_memory_operand (low[0], SImode)); + gcc_assert (!flag_pic + || !non_pic_external_memory_operand (low[2], SImode)); + gcc_assert (!flag_pic + || !non_pic_external_memory_operand (low[0], SImode)); #endif /* No reason to add a 0 to the low part and thus no carry, so just diff --git a/gcc/config/vax/vax.h b/gcc/config/vax/vax.h index c1d0171..8b2b2d1 100644 --- a/gcc/config/vax/vax.h +++ b/gcc/config/vax/vax.h @@ -120,12 +120,12 @@ along with GCC; see the file COPYING3. If not see from 0 to just below FIRST_PSEUDO_REGISTER. All registers that the compiler knows about must be given numbers, even those that are not normally considered general registers. */ -#define FIRST_PSEUDO_REGISTER 16 +#define FIRST_PSEUDO_REGISTER 17 /* 1 for registers that have pervasive standard uses and are not available for the register allocator. On the VAX, these are the AP, FP, SP and PC. */ -#define FIXED_REGISTERS {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1} +#define FIXED_REGISTERS {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} /* 1 for registers not available across function calls. These must include the FIXED_REGISTERS and also any @@ -133,7 +133,7 @@ along with GCC; see the file COPYING3. If not see The latter must include the registers where values are returned and the register where structure-value addresses are passed. Aside from that, you can include as many other registers as you like. */ -#define CALL_USED_REGISTERS {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1} +#define CALL_USED_REGISTERS {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1} /* Specify the registers used for certain standard purposes. The values of these macros are register numbers. */ @@ -442,6 +442,11 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES }; of a shift count. */ /* #define SHIFT_COUNT_TRUNCATED */ +/* We need to reject symbol references in PIC code except for address + loads, handled elsewhere. */ +#define LEGITIMATE_PIC_OPERAND_P(x) \ + vax_acceptable_pic_operand_p ((x), false, false) + /* Specify the machine mode that pointers have. After generation of rtl, the compiler makes no further distinction between pointers and any other objects of this machine mode. */ @@ -460,24 +465,11 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES }; #define BRANCH_COST(speed_p, predictable_p) 0 -/* Tell final.c how to eliminate redundant test instructions. */ - -/* Here we define machine-dependent flags and fields in cc_status - (see `conditions.h'). No extra ones are needed for the VAX. */ - -/* Store in cc_status the expressions - that the condition codes will describe - after execution of an instruction whose pattern is EXP. - Do not alter them if the instruction would not alter the cc's. */ - -#define NOTICE_UPDATE_CC(EXP, INSN) \ - vax_notice_update_cc ((EXP), (INSN)) - -#define OUTPUT_JUMP(NORMAL, FLOAT, NO_OV) \ - { if (cc_status.flags & CC_NO_OVERFLOW) \ - return NO_OV; \ - return NORMAL; \ - } +/* Given a comparison code (NE, EQ, etc.) and the operands of a COMPARE, + return the mode to be used for the comparison. As we have the same + interpretation of condition codes across all the instructions we just + return the narrowest mode suitable for the comparison code requested. */ +#define SELECT_CC_MODE(OP, X, Y) vax_select_cc_mode (OP, X, Y) /* Control the assembler format that we output. */ @@ -512,7 +504,8 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES }; #define REGISTER_PREFIX "" #define REGISTER_NAMES \ { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \ - "r8", "r9", "r10", "r11", "ap", "fp", "sp", "pc", } + "r8", "r9", "r10", "r11", "ap", "fp", "sp", "pc", \ + "psl" } /* This is BSD, so it wants DBX format. */ @@ -678,3 +671,7 @@ VAX operand formatting codes: by the proper FDE definition. */ #define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, PC_REGNUM) +/* Upon failure to find the bit the FFS hardware instruction returns + the position of the bit immediately following the field specified. */ +#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) \ + ((VALUE) = GET_MODE_BITSIZE (MODE), 2) diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md index 4897ce4..b8cf4ee 100644 --- a/gcc/config/vax/vax.md +++ b/gcc/config/vax/vax.md @@ -22,9 +22,6 @@ ;;- the first one in the file is chosen. ;;- ;;- See file "rtl.def" for documentation on define_insn, match_*, et al. -;;- -;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code -;;- updates for most instructions. ;; UNSPEC_VOLATILE usage: @@ -40,6 +37,8 @@ (VAX_FP_REGNUM 13) ; Register 13 contains the frame pointer (VAX_SP_REGNUM 14) ; Register 14 contains the stack pointer (VAX_PC_REGNUM 15) ; Register 15 contains the program counter + (VAX_PSL_REGNUM 16) ; Register 16 contains the processor status + ; and condition codes in particular ] ) @@ -57,34 +56,96 @@ ;; Some output patterns want integer immediates with a prefix... (define_mode_attr iprefx [(QI "B") (HI "H") (SI "N")]) +(define_mode_iterator VAXcc [CC CCN CCNZ CCZ]) +(define_mode_iterator VAXccnz [CCN CCNZ CCZ]) +(define_mode_attr cc [(CC "cc") (CCN "ccn") (CCNZ "ccnz") (CCZ "ccz")]) + +(define_code_iterator any_extract [sign_extract zero_extract]) + ;; (include "constraints.md") (include "predicates.md") -(define_insn "*cmp<mode>" - [(set (cc0) - (compare (match_operand:VAXint 0 "nonimmediate_operand" "nrmT,nrmT") - (match_operand:VAXint 1 "general_operand" "I,nrmT")))] +;; Make instructions that set the N, N+Z, and Z condition codes respectively. +(define_subst "subst_<cc>" + [(set (match_operand 0 "") + (match_operand 1 "")) + (clobber (reg:CC VAX_PSL_REGNUM))] + "" + [(set (reg:VAXccnz VAX_PSL_REGNUM) + (compare:VAXccnz (match_dup 1) + (const_int 0))) + (set (match_dup 0) + (match_dup 1))]) + +(define_subst "subst_f<cc>" + [(set (match_operand 0 "") + (match_operand 1 "")) + (clobber (reg:CC VAX_PSL_REGNUM))] "" + [(set (reg:VAXccnz VAX_PSL_REGNUM) + (compare:VAXccnz (match_dup 1) + (const_double_zero))) + (set (match_dup 0) + (match_dup 1))]) + +;; Select all from the attributes below that apply to a given insn that +;; has a clobber on CC for the comparison elimination pass to use it in +;; place of a subsequent comparison instruction matching the mode used +;; by a comparison operator in branch. +;; +;; For example a branch doing `eq' in SImode will use `*cmpsi_ccz', so +;; to eliminate it a `*movsi_ccz', etc. pattern will be required via the +;; `ccz' substitution. Analogously for the other CC modes. +;; +;; The general `cc' mode, which sets all of the C, N, V and Z condition +;; codes, has to be handled specially as it makes no sense for the usual +;; comparison against zero, so no substitution has been defined for it. +(define_subst_attr "ccn" "subst_ccn" "" "_ccn") +(define_subst_attr "ccnz" "subst_ccnz" "" "_ccnz") +(define_subst_attr "ccz" "subst_ccz" "" "_ccz") +(define_subst_attr "fccn" "subst_fccn" "" "_ccn") +(define_subst_attr "fccnz" "subst_fccnz" "" "_ccnz") +(define_subst_attr "fccz" "subst_fccz" "" "_ccz") + +(define_insn "*cmp<VAXint:mode>_<VAXcc:mode>" + [(set (reg:VAXcc VAX_PSL_REGNUM) + (compare:VAXcc (match_operand:VAXint 0 "general_operand" "nrmT,nrmT") + (match_operand:VAXint 1 "general_operand" "I,nrmT")))] + "reload_completed" "@ tst<VAXint:isfx> %0 cmp<VAXint:isfx> %0,%1") -(define_insn "*cmp<mode>" - [(set (cc0) - (compare (match_operand:VAXfp 0 "general_operand" "gF,gF") - (match_operand:VAXfp 1 "general_operand" "G,gF")))] - "" +;; We don't have a CMPQ instruction, but we can set the N and Z condition +;; codes with MOVQ, and also this comparison can be folded into a preceding +;; operation by the post-reload comparison elimination pass. +(define_insn "*cmpdi_<VAXccnz:mode>" + [(set (reg:VAXccnz VAX_PSL_REGNUM) + (compare:VAXccnz (match_operand:DI 0 "general_operand" "r,nmT") + (match_operand:DI 1 "const_zero_operand" "I,I"))) + (clobber (match_scratch:DI 2 "=X,r"))] + "reload_completed" + "@ + movq %0,%0 + movq %0,%2") + +(define_insn "*cmp<VAXfp:mode>_<VAXccnz:mode>" + [(set (reg:VAXccnz VAX_PSL_REGNUM) + (compare:VAXccnz (match_operand:VAXfp 0 "general_operand" "gF,gF") + (match_operand:VAXfp 1 "general_operand" "G,gF")))] + "reload_completed" "@ tst<VAXfp:fsfx> %0 cmp<VAXfp:fsfx> %0,%1") -(define_insn "*bit<mode>" - [(set (cc0) - (compare (and:VAXint (match_operand:VAXint 0 "general_operand" "nrmT") - (match_operand:VAXint 1 "general_operand" "nrmT")) - (const_int 0)))] - "" +(define_insn "*bit<VAXint:mode>_<VAXccnz:mode>" + [(set (reg:VAXccnz VAX_PSL_REGNUM) + (compare:VAXccnz + (and:VAXint (match_operand:VAXint 0 "general_operand" "nrmT") + (match_operand:VAXint 1 "general_operand" "nrmT")) + (const_int 0)))] + "reload_completed" "bit<VAXint:isfx> %0,%1") ;; The VAX has no sCOND insns. It does have add/subtract with carry @@ -95,25 +156,76 @@ ;; and has been deleted. -(define_insn "mov<mode>" +(define_insn_and_split "mov<mode>" [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g") (match_operand:VAXfp 1 "general_operand" "G,gF"))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (match_dup 1)) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*mov<mode><fccn><fccnz><fccz>" + [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g") + (match_operand:VAXfp 1 "general_operand" "G,gF")) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "@ clr<VAXfp:fsfx> %0 mov<VAXfp:fsfx> %1,%0") ;; Some VAXen don't support this instruction. -;;(define_insn "movti" -;; [(set (match_operand:TI 0 "general_operand" "=g") +;;(define_insn_and_split "movti" +;; [(set (match_operand:TI 0 "nonimmediate_operand" "=g") ;; (match_operand:TI 1 "general_operand" "g"))] ;; "" -;; "movh %1,%0") - -(define_insn "movdi" +;; "#" +;; "reload_completed" +;; [(parallel +;; [(set (match_dup 0) +;; (match_dup 1)) +;; (clobber (reg:CC VAX_PSL_REGNUM))])] +;; "") +;; +;;(define_insn "*movti<ccn><ccnz><ccz>" +;; [(set (match_operand:TI 0 "nonimmediate_operand" "=g") +;; (match_operand:TI 1 "general_operand" "g")) +;; (clobber (reg:CC VAX_PSL_REGNUM))] +;; "reload_completed" +;; "movo %1,%0") + +(define_insn_and_split "movdi" [(set (match_operand:DI 0 "nonimmediate_operand" "=g") (match_operand:DI 1 "general_operand" "g"))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (match_dup 1)) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +;; In some cases `vax_output_int_move' splits a `DImode' move into a pair +;; of `SImode' moves, in which case the flags aren't usefully set. Have +;; separate patterns then, for the cases where the move may and may not be +;; split each. We use the outer condition only so in some cases we will +;; fail to notice the move does not actually get split, but this is OK. +(define_insn "*movdi_maybe_split" + [(set (match_operand:DI 0 "nonimmediate_operand" "=g") + (match_operand:DI 1 "general_operand" "g")) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed && vax_maybe_split_dimode_move (operands)" + "* return vax_output_int_move (insn, operands, DImode);") + +(define_insn "*movdi_unsplit<ccn><ccnz><ccz>" + [(set (match_operand:DI 0 "nonimmediate_operand" "=g") + (match_operand:DI 1 "general_operand" "g")) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed && !vax_maybe_split_dimode_move (operands)" "* return vax_output_int_move (insn, operands, DImode);") ;; The VAX move instructions have space-time tradeoffs. On a MicroVAX @@ -155,22 +267,61 @@ #endif }") -(define_insn "movsi_2" +(define_insn_and_split "movsi_2" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (match_operand:SI 1 "nonsymbolic_operand" "nrmT"))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (match_dup 1)) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*movsi_2<ccn><ccnz><ccz>" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (match_operand:SI 1 "nonsymbolic_operand" "nrmT")) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "* return vax_output_int_move (insn, operands, SImode);") -(define_insn "mov<mode>" +(define_insn_and_split "mov<mode>" [(set (match_operand:VAXintQH 0 "nonimmediate_operand" "=g") (match_operand:VAXintQH 1 "general_operand" "g"))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (match_dup 1)) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*mov<mode><ccn><ccnz><ccz>" + [(set (match_operand:VAXintQH 0 "nonimmediate_operand" "=g") + (match_operand:VAXintQH 1 "general_operand" "g")) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "* return vax_output_int_move (insn, operands, <MODE>mode);") -(define_insn "movstricthi" - [(set (strict_low_part (match_operand:HI 0 "register_operand" "+g")) +(define_insn_and_split "movstricthi" + [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r")) (match_operand:HI 1 "general_operand" "g"))] "" + "#" + "reload_completed" + [(parallel + [(set (strict_low_part (match_dup 0)) + (match_dup 1)) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*movstricthi<ccn><ccnz><ccz>" + [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r")) + (match_operand:HI 1 "general_operand" "g")) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "* { if (CONST_INT_P (operands[1])) @@ -188,10 +339,23 @@ return \"movw %1,%0\"; }") -(define_insn "movstrictqi" - [(set (strict_low_part (match_operand:QI 0 "register_operand" "+g")) +(define_insn_and_split "movstrictqi" + [(set (strict_low_part (match_operand:QI 0 "register_operand" "+r")) (match_operand:QI 1 "general_operand" "g"))] "" + "#" + "reload_completed" + [(parallel + [(set (strict_low_part (match_dup 0)) + (match_dup 1)) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*movstrictqi<ccn><ccnz><ccz>" + [(set (strict_low_part (match_operand:QI 0 "register_operand" "+r")) + (match_operand:QI 1 "general_operand" "g")) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "* { if (CONST_INT_P (operands[1])) @@ -206,16 +370,28 @@ }") ;; This is here to accept 4 arguments and pass the first 3 along -;; to the cpymemhi1 pattern that really does the work. +;; to the movmemhi1 pattern that really does the work. (define_expand "cpymemhi" - [(set (match_operand:BLK 0 "general_operand" "=g") - (match_operand:BLK 1 "general_operand" "g")) - (use (match_operand:HI 2 "general_operand" "g")) + [(set (match_operand:BLK 0 "memory_operand" "") + (match_operand:BLK 1 "memory_operand" "")) + (use (match_operand:HI 2 "general_operand" "")) (match_operand 3 "" "")] "" " { - emit_insn (gen_cpymemhi1 (operands[0], operands[1], operands[2])); + emit_insn (gen_movmemhi1 (operands[0], operands[1], operands[2])); + DONE; +}") + +(define_expand "movmemhi" + [(set (match_operand:BLK 0 "memory_operand" "") + (match_operand:BLK 1 "memory_operand" "")) + (use (match_operand:HI 2 "general_operand" "")) + (match_operand 3 "" "")] + "" + " +{ + emit_insn (gen_movmemhi1 (operands[0], operands[1], operands[2])); DONE; }") @@ -224,7 +400,7 @@ ;; that anything generated as this insn will be recognized as one ;; and that it won't successfully combine with anything. -(define_insn "cpymemhi1" +(define_insn_and_split "movmemhi1" [(set (match_operand:BLK 0 "memory_operand" "=o") (match_operand:BLK 1 "memory_operand" "o")) (use (match_operand:HI 2 "general_operand" "g")) @@ -235,90 +411,286 @@ (clobber (reg:SI 4)) (clobber (reg:SI 5))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (match_dup 1)) + (use (match_dup 2)) + (clobber (reg:SI 0)) + (clobber (reg:SI 1)) + (clobber (reg:SI 2)) + (clobber (reg:SI 3)) + (clobber (reg:SI 4)) + (clobber (reg:SI 5)) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*movmemhi1" + [(set (match_operand:BLK 0 "memory_operand" "=o") + (match_operand:BLK 1 "memory_operand" "o")) + (use (match_operand:HI 2 "general_operand" "g")) + (clobber (reg:SI 0)) + (clobber (reg:SI 1)) + (clobber (reg:SI 2)) + (clobber (reg:SI 3)) + (clobber (reg:SI 4)) + (clobber (reg:SI 5)) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "movc3 %2,%1,%0") ;; Extension and truncation insns. -(define_insn "truncsiqi2" +(define_insn_and_split "truncsiqi2" [(set (match_operand:QI 0 "nonimmediate_operand" "=g") (truncate:QI (match_operand:SI 1 "nonimmediate_operand" "nrmT")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (truncate:QI (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*truncsiqi2<ccn><ccnz><ccz>" + [(set (match_operand:QI 0 "nonimmediate_operand" "=g") + (truncate:QI (match_operand:SI 1 "nonimmediate_operand" "nrmT"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "cvtlb %1,%0") -(define_insn "truncsihi2" +(define_insn_and_split "truncsihi2" [(set (match_operand:HI 0 "nonimmediate_operand" "=g") (truncate:HI (match_operand:SI 1 "nonimmediate_operand" "nrmT")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (truncate:HI (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*truncsihi2<ccn><ccnz><ccz>" + [(set (match_operand:HI 0 "nonimmediate_operand" "=g") + (truncate:HI (match_operand:SI 1 "nonimmediate_operand" "nrmT"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "cvtlw %1,%0") -(define_insn "trunchiqi2" +(define_insn_and_split "trunchiqi2" [(set (match_operand:QI 0 "nonimmediate_operand" "=g") (truncate:QI (match_operand:HI 1 "nonimmediate_operand" "g")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (truncate:QI (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*trunchiqi2<ccn><ccnz><ccz>" + [(set (match_operand:QI 0 "nonimmediate_operand" "=g") + (truncate:QI (match_operand:HI 1 "nonimmediate_operand" "g"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "cvtwb %1,%0") -(define_insn "extendhisi2" +(define_insn_and_split "extendhisi2" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (sign_extend:SI (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*extendhisi2<ccn><ccnz><ccz>" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "cvtwl %1,%0") -(define_insn "extendqihi2" +(define_insn_and_split "extendqihi2" [(set (match_operand:HI 0 "nonimmediate_operand" "=g") (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (sign_extend:HI (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*extendqihi2<ccn><ccnz><ccz>" + [(set (match_operand:HI 0 "nonimmediate_operand" "=g") + (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "cvtbw %1,%0") -(define_insn "extendqisi2" +(define_insn_and_split "extendqisi2" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (sign_extend:SI (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*extendqisi2<ccn><ccnz><ccz>" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "cvtbl %1,%0") -(define_insn "extendsfdf2" +(define_insn_and_split "extendsfdf2" [(set (match_operand:DF 0 "nonimmediate_operand" "=g") (float_extend:DF (match_operand:SF 1 "general_operand" "gF")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (float_extend:DF (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*extendsfdf2<fccn><fccnz><fccz>" + [(set (match_operand:DF 0 "nonimmediate_operand" "=g") + (float_extend:DF (match_operand:SF 1 "general_operand" "gF"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "cvtf%# %1,%0") -(define_insn "truncdfsf2" +(define_insn_and_split "truncdfsf2" [(set (match_operand:SF 0 "nonimmediate_operand" "=g") (float_truncate:SF (match_operand:DF 1 "general_operand" "gF")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (float_truncate:SF (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*truncdfsf2<fccn><fccnz><fccz>" + [(set (match_operand:SF 0 "nonimmediate_operand" "=g") + (float_truncate:SF (match_operand:DF 1 "general_operand" "gF"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "cvt%#f %1,%0") -(define_insn "zero_extendhisi2" +(define_insn_and_split "zero_extendhisi2" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (zero_extend:SI (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*zero_extendhisi2<ccn><ccnz><ccz>" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "movzwl %1,%0") -(define_insn "zero_extendqihi2" +(define_insn_and_split "zero_extendqihi2" [(set (match_operand:HI 0 "nonimmediate_operand" "=g") (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (zero_extend:HI (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*zero_extendqihi2<ccn><ccnz><ccz>" + [(set (match_operand:HI 0 "nonimmediate_operand" "=g") + (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "movzbw %1,%0") -(define_insn "zero_extendqisi2" +(define_insn_and_split "zero_extendqisi2" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (zero_extend:SI (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*zero_extendqisi2<ccn><ccnz><ccz>" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "movzbl %1,%0") ;; Fix-to-float conversion insns. -(define_insn "float<VAXint:mode><VAXfp:mode>2" +(define_insn_and_split "float<VAXint:mode><VAXfp:mode>2" [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g") (float:VAXfp (match_operand:VAXint 1 "nonimmediate_operand" "g")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (float:VAXfp (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*float<VAXint:mode><VAXfp:mode>2<fccn><fccnz><fccz>" + [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g") + (float:VAXfp (match_operand:VAXint 1 "nonimmediate_operand" "g"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "cvt<VAXint:isfx><VAXfp:fsfx> %1,%0") ;; Float-to-fix conversion insns. -(define_insn "fix_trunc<VAXfp:mode><VAXint:mode>2" +(define_insn_and_split "fix_trunc<VAXfp:mode><VAXint:mode>2" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g") (fix:VAXint (match_operand:VAXfp 1 "general_operand" "gF")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (fix:VAXint (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*fix_trunc<VAXfp:mode><VAXint:mode>2<ccn><ccnz><ccz>" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g") + (fix:VAXint (match_operand:VAXfp 1 "general_operand" "gF"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "cvt<VAXfp:fsfx><VAXint:isfx> %1,%0") (define_expand "fixuns_trunc<VAXfp:mode><VAXint:mode>2" @@ -328,49 +700,51 @@ ;;- All kinds of add instructions. -(define_insn "add<mode>3" +(define_insn_and_split "add<mode>3" [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g,g") (plus:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF,gF") (match_operand:VAXfp 2 "general_operand" "gF,0,gF")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (plus:VAXfp (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*add<mode>3<fccn><fccnz><fccz>" + [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g,g") + (plus:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF,gF") + (match_operand:VAXfp 2 "general_operand" "gF,0,gF"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "@ add<VAXfp:fsfx>2 %2,%0 add<VAXfp:fsfx>2 %1,%0 add<VAXfp:fsfx>3 %1,%2,%0") -(define_insn "pushlclsymreg" - [(set (match_operand:SI 0 "push_operand" "=g") - (plus:SI (match_operand:SI 1 "register_operand" "%r") - (match_operand:SI 2 "local_symbolic_operand" "i")))] - "flag_pic" - "pushab %a2[%1]") - -(define_insn "pushextsymreg" - [(set (match_operand:SI 0 "push_operand" "=g") - (plus:SI (match_operand:SI 1 "register_operand" "%r") - (match_operand:SI 2 "external_symbolic_operand" "i")))] - "flag_pic" - "pushab %a2[%1]") - -(define_insn "movlclsymreg" - [(set (match_operand:SI 0 "nonimmediate_operand" "=g") - (plus:SI (match_operand:SI 1 "register_operand" "%r") - (match_operand:SI 2 "local_symbolic_operand" "i")))] - "flag_pic" - "movab %a2[%1],%0") - -(define_insn "movextsymreg" - [(set (match_operand:SI 0 "nonimmediate_operand" "=g") - (plus:SI (match_operand:SI 1 "register_operand" "%r") - (match_operand:SI 2 "external_symbolic_operand" "i")))] - "flag_pic" - "movab %a2[%1],%0") - -(define_insn "add<mode>3" +(define_insn_and_split "add<mode>3" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g") (plus:VAXint (match_operand:VAXint 1 "general_operand" "nrmT") (match_operand:VAXint 2 "general_operand" "nrmT")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (plus:VAXint (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*add<mode>3<ccn><ccnz><ccz>" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g") + (plus:VAXint (match_operand:VAXint 1 "general_operand" "nrmT") + (match_operand:VAXint 2 "general_operand" "nrmT"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "* return vax_output_int_add (insn, operands, <MODE>mode);") (define_expand "adddi3" @@ -380,37 +754,109 @@ "!reload_in_progress" "vax_expand_addsub_di_operands (operands, PLUS); DONE;") -(define_insn "adcdi3" +(define_insn_and_split "adcdi3" [(set (match_operand:DI 0 "nonimmediate_addsub_di_operand" "=Rr") (plus:DI (match_operand:DI 1 "general_addsub_di_operand" "%0") (match_operand:DI 2 "general_addsub_di_operand" "nRr")))] "TARGET_QMATH" + "#" + "&& reload_completed" + [(parallel + [(set (match_dup 0) + (plus:DI (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*adcdi3<ccn>" + [(set (match_operand:DI 0 "nonimmediate_addsub_di_operand" "=Rr") + (plus:DI (match_operand:DI 1 "general_addsub_di_operand" "%0") + (match_operand:DI 2 "general_addsub_di_operand" "nRr"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "TARGET_QMATH && reload_completed" "* return vax_output_int_add (insn, operands, DImode);") ;; The add-with-carry (adwc) instruction only accepts two operands. -(define_insn "adddi3_old" +(define_insn_and_split "adddi3_old" [(set (match_operand:DI 0 "nonimmediate_operand" "=ro>,ro>") (plus:DI (match_operand:DI 1 "general_operand" "%0,ro>") (match_operand:DI 2 "general_operand" "Fsro,Fs")))] "!TARGET_QMATH" + "#" + "&& reload_completed" + [(parallel + [(set (match_dup 0) + (plus:DI (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*adddi3_old<ccn>" + [(set (match_operand:DI 0 "nonimmediate_operand" "=ro>,ro>") + (plus:DI (match_operand:DI 1 "general_operand" "%0,ro>") + (match_operand:DI 2 "general_operand" "Fsro,Fs"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "!TARGET_QMATH && reload_completed" "* return vax_output_int_add (insn, operands, DImode);") ;;- All kinds of subtract instructions. -(define_insn "sub<mode>3" +(define_insn_and_split "sub<mode>3" [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g") (minus:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF") (match_operand:VAXfp 2 "general_operand" "gF,gF")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (minus:VAXfp (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*sub<mode>3<fccn><fccnz><fccz>" + [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g") + (minus:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF") + (match_operand:VAXfp 2 "general_operand" "gF,gF"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "@ sub<VAXfp:fsfx>2 %2,%0 sub<VAXfp:fsfx>3 %2,%1,%0") -(define_insn "sub<mode>3" +(define_insn_and_split "sub<mode>3" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g") (minus:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT") (match_operand:VAXint 2 "general_operand" "nrmT,nrmT")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (minus:VAXint (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*sub<mode>3<ccn><ccnz><ccz>" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g") + (minus:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT") + (match_operand:VAXint 2 "general_operand" "nrmT,nrmT"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" + "@ + sub<VAXint:isfx>2 %2,%0 + sub<VAXint:isfx>3 %2,%1,%0") + +(define_insn "*sub<mode>3_cc" + [(set (reg:CC VAX_PSL_REGNUM) + (compare:CC (match_operand:VAXint 1 "general_operand" "0,nrmT") + (match_operand:VAXint 2 "general_operand" "nrmT,nrmT"))) + (set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g") + (minus:VAXint (match_dup 1) + (match_dup 2)))] + "reload_completed" "@ sub<VAXint:isfx>2 %2,%0 sub<VAXint:isfx>3 %2,%1,%0") @@ -422,74 +868,192 @@ "!reload_in_progress" "vax_expand_addsub_di_operands (operands, MINUS); DONE;") -(define_insn "sbcdi3" +(define_insn_and_split "sbcdi3" [(set (match_operand:DI 0 "nonimmediate_addsub_di_operand" "=Rr,Rr") (minus:DI (match_operand:DI 1 "general_addsub_di_operand" "0,I") (match_operand:DI 2 "general_addsub_di_operand" "nRr,Rr")))] "TARGET_QMATH" + "#" + "&& reload_completed" + [(parallel + [(set (match_dup 0) + (minus:DI (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*sbcdi3<ccn>" + [(set (match_operand:DI 0 "nonimmediate_addsub_di_operand" "=Rr,Rr") + (minus:DI (match_operand:DI 1 "general_addsub_di_operand" "0,I") + (match_operand:DI 2 "general_addsub_di_operand" "nRr,Rr"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "TARGET_QMATH && reload_completed" "* return vax_output_int_subtract (insn, operands, DImode);") ;; The subtract-with-carry (sbwc) instruction only takes two operands. -(define_insn "subdi3_old" +(define_insn_and_split "subdi3_old" [(set (match_operand:DI 0 "nonimmediate_operand" "=or>,or>") (minus:DI (match_operand:DI 1 "general_operand" "0,or>") (match_operand:DI 2 "general_operand" "Fsor,Fs")))] "!TARGET_QMATH" + "#" + "&& reload_completed" + [(parallel + [(set (match_dup 0) + (minus:DI (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*subdi3_old<ccn>" + [(set (match_operand:DI 0 "nonimmediate_operand" "=or>,or>") + (minus:DI (match_operand:DI 1 "general_operand" "0,or>") + (match_operand:DI 2 "general_operand" "Fsor,Fs"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "!TARGET_QMATH && reload_completed" "* return vax_output_int_subtract (insn, operands, DImode);") ;;- Multiply instructions. -(define_insn "mul<mode>3" +(define_insn_and_split "mul<mode>3" [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g,g") (mult:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF,gF") (match_operand:VAXfp 2 "general_operand" "gF,0,gF")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (mult:VAXfp (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*mul<mode>3<fccn><fccnz><fccz>" + [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g,g") + (mult:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF,gF") + (match_operand:VAXfp 2 "general_operand" "gF,0,gF"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "@ mul<VAXfp:fsfx>2 %2,%0 mul<VAXfp:fsfx>2 %1,%0 mul<VAXfp:fsfx>3 %1,%2,%0") -(define_insn "mul<mode>3" +(define_insn_and_split "mul<mode>3" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g") (mult:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT") (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (mult:VAXint (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*mul<mode>3<ccn><ccnz><ccz>" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g") + (mult:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT") + (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "@ mul<VAXint:isfx>2 %2,%0 mul<VAXint:isfx>2 %1,%0 mul<VAXint:isfx>3 %1,%2,%0") -(define_insn "mulsidi3" +(define_insn_and_split "mulsidi3" [(set (match_operand:DI 0 "nonimmediate_operand" "=g") - (mult:DI (sign_extend:DI - (match_operand:SI 1 "nonimmediate_operand" "nrmT")) - (sign_extend:DI - (match_operand:SI 2 "nonimmediate_operand" "nrmT"))))] - "" + (mult:DI + (sign_extend:DI (match_operand:SI 1 "general_operand" "nrmT")) + (sign_extend:DI (match_operand:SI 2 "general_operand" "nrmT"))))] + "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (mult:DI + (sign_extend:DI (match_dup 1)) + (sign_extend:DI (match_dup 2)))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*mulsidi3<ccn><ccnz><ccz>" + [(set (match_operand:DI 0 "nonimmediate_operand" "=g") + (mult:DI + (sign_extend:DI (match_operand:SI 1 "general_operand" "nrmT")) + (sign_extend:DI (match_operand:SI 2 "general_operand" "nrmT")))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "emul %1,%2,$0,%0") -(define_insn "" +(define_insn_and_split "*maddsidi4" [(set (match_operand:DI 0 "nonimmediate_operand" "=g") (plus:DI - (mult:DI (sign_extend:DI - (match_operand:SI 1 "nonimmediate_operand" "nrmT")) - (sign_extend:DI - (match_operand:SI 2 "nonimmediate_operand" "nrmT"))) - (sign_extend:DI (match_operand:SI 3 "nonimmediate_operand" "g"))))] - "" + (mult:DI + (sign_extend:DI (match_operand:SI 1 "general_operand" "nrmT")) + (sign_extend:DI (match_operand:SI 2 "general_operand" "nrmT"))) + (sign_extend:DI (match_operand:SI 3 "general_operand" "g"))))] + "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (plus:DI + (mult:DI + (sign_extend:DI (match_dup 1)) + (sign_extend:DI (match_dup 2))) + (sign_extend:DI (match_dup 3)))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*maddsidi4_2<ccn><ccnz><ccz>" + [(set (match_operand:DI 0 "nonimmediate_operand" "=g") + (plus:DI + (mult:DI + (sign_extend:DI (match_operand:SI 1 "general_operand" "nrmT")) + (sign_extend:DI (match_operand:SI 2 "general_operand" "nrmT"))) + (sign_extend:DI (match_operand:SI 3 "nonimmediate_operand" "g")))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "emul %1,%2,%3,%0") ;; 'F' constraint means type CONST_DOUBLE -(define_insn "" +(define_insn_and_split "*maddsidi4_const" + [(set (match_operand:DI 0 "nonimmediate_operand" "=g") + (plus:DI + (mult:DI + (sign_extend:DI (match_operand:SI 1 "general_operand" "nrmT")) + (sign_extend:DI (match_operand:SI 2 "general_operand" "nrmT"))) + (match_operand:DI 3 "immediate_operand" "F")))] + "GET_CODE (operands[3]) == CONST_DOUBLE + && CONST_DOUBLE_HIGH (operands[3]) == (CONST_DOUBLE_LOW (operands[3]) >> 31)" + "#" + "&& reload_completed" + [(parallel + [(set (match_dup 0) + (plus:DI + (mult:DI + (sign_extend:DI (match_dup 1)) + (sign_extend:DI (match_dup 2))) + (match_dup 3))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*maddsidi4_const_2<ccn><ccnz><ccz>" [(set (match_operand:DI 0 "nonimmediate_operand" "=g") (plus:DI - (mult:DI (sign_extend:DI - (match_operand:SI 1 "nonimmediate_operand" "nrmT")) - (sign_extend:DI - (match_operand:SI 2 "nonimmediate_operand" "nrmT"))) - (match_operand:DI 3 "immediate_operand" "F")))] + (mult:DI + (sign_extend:DI (match_operand:SI 1 "general_operand" "nrmT")) + (sign_extend:DI (match_operand:SI 2 "general_operand" "nrmT"))) + (match_operand:DI 3 "immediate_operand" "F"))) + (clobber (reg:CC VAX_PSL_REGNUM))] "GET_CODE (operands[3]) == CONST_DOUBLE - && CONST_DOUBLE_HIGH (operands[3]) == (CONST_DOUBLE_LOW (operands[3]) >> 31)" + && CONST_DOUBLE_HIGH (operands[3]) == (CONST_DOUBLE_LOW (operands[3]) >> 31) + && reload_completed" "* { if (CONST_DOUBLE_HIGH (operands[3])) @@ -499,35 +1063,86 @@ ;;- Divide instructions. -(define_insn "div<mode>3" +(define_insn_and_split "div<mode>3" [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g") (div:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF") (match_operand:VAXfp 2 "general_operand" "gF,gF")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (div:VAXfp (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*div<mode>3<fccn><fccnz><fccz>" + [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g") + (div:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF") + (match_operand:VAXfp 2 "general_operand" "gF,gF"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "@ div<VAXfp:fsfx>2 %2,%0 div<VAXfp:fsfx>3 %2,%1,%0") -(define_insn "div<mode>3" +(define_insn_and_split "div<mode>3" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g") (div:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT") (match_operand:VAXint 2 "general_operand" "nrmT,nrmT")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (div:VAXint (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*div<mode>3<ccn><ccnz><ccz>" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g") + (div:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT") + (match_operand:VAXint 2 "general_operand" "nrmT,nrmT"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "@ div<VAXint:isfx>2 %2,%0 div<VAXint:isfx>3 %2,%1,%0") -;This is left out because it is very slow; -;we are better off programming around the "lack" of this insn. -;(define_insn "divmoddisi4" -; [(set (match_operand:SI 0 "general_operand" "=g") -; (div:SI (match_operand:DI 1 "general_operand" "g") -; (match_operand:SI 2 "general_operand" "g"))) -; (set (match_operand:SI 3 "general_operand" "=g") -; (mod:SI (match_operand:DI 1 "general_operand" "g") -; (match_operand:SI 2 "general_operand" "g")))] -; "" -; "ediv %2,%1,%0,%3") +;; This is left out because it is very slow; +;; we are better off programming around the "lack" of this insn. +;;(define_insn_and_split "divmoddisi4" +;; [(set (match_operand:SI 0 "nonimmediate_operand" "=g") +;; (div:SI (match_operand:DI 1 "general_operand" "g") +;; (match_operand:SI 2 "general_operand" "g"))) +;; (set (match_operand:SI 3 "nonimmediate_operand" "=g") +;; (mod:SI (match_dup 1) +;; (match_dup 2)))] +;; "" +;; "#" +;; "reload_completed" +;; [(parallel +;; [(set (match_dup 0) +;; (div:SI (match_dup 1) +;; (match_dup 2))) +;; (set (match_dup 3) +;; (mod:SI (match_dup 1) +;; (match_dup 2))) +;; (clobber (reg:CC VAX_PSL_REGNUM))])] +;; "") +;; +;;(define_insn "*divmoddisi4<ccn><ccnz><ccz>" +;; [(set (match_operand:SI 0 "nonimmediate_operand" "=g") +;; (div:SI (match_operand:DI 1 "general_operand" "g") +;; (match_operand:SI 2 "general_operand" "g"))) +;; (set (match_operand:SI 3 "nonimmediate_operand" "=g") +;; (mod:SI (match_dup 1) +;; (match_dup 2))) +;; (clobber (reg:CC VAX_PSL_REGNUM))] +;; "reload_completed" +;; "ediv %2,%1,%0,%3") ;; Bit-and on the VAX is done with a clear-bits insn. (define_expand "and<mode>3" @@ -553,11 +1168,29 @@ operands[1] = expand_unop (<MODE>mode, one_cmpl_optab, op1, 0, 1); }") -(define_insn "*and<mode>" +(define_insn_and_split "*and<mode>3" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g") - (and:VAXint (not:VAXint (match_operand:VAXint 1 "general_operand" "nrmT,nrmT")) + (and:VAXint (not:VAXint + (match_operand:VAXint 1 "general_operand" "nrmT,nrmT")) (match_operand:VAXint 2 "general_operand" "0,nrmT")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (and:VAXint (not:VAXint + (match_dup 1)) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*and<mode>3_2<ccn><ccnz><ccz>" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g") + (and:VAXint (not:VAXint + (match_operand:VAXint 1 "general_operand" "nrmT,nrmT")) + (match_operand:VAXint 2 "general_operand" "0,nrmT"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "@ bic<VAXint:isfx>2 %1,%0 bic<VAXint:isfx>3 %1,%2,%0") @@ -567,23 +1200,80 @@ ;; longer a problem. However, having these patterns allows optimization ;; opportunities in combine.c. -(define_insn "*and<mode>_const_int" +(define_insn_and_split "*and<mode>3_const_int" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g") (and:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT") (match_operand:VAXint 2 "const_int_operand" "n,n")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (and:VAXint (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*and<mode>3_2_const_int<ccn><ccnz><ccz>" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g") + (and:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT") + (match_operand:VAXint 2 "const_int_operand" "n,n"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "@ bic<VAXint:isfx>2 %<VAXint:iprefx>2,%0 bic<VAXint:isfx>3 %<VAXint:iprefx>2,%1,%0") +;; We have no direct AND operation and consequently the RTL sequence +;; the "and<mode>3" pattern produces does not match the instruction +;; the "*bit<mode>" pattern does for the purpose of the compare +;; elimination pass. Try to get rid of the extra operation by hand +;; and where the sequence is used to set the condition codes only +;; convert MNEG/BIC => BIT. +(define_peephole2 + [(parallel + [(set (match_operand:VAXint 0 "register_operand") + (not:VAXint (match_operand:VAXint 1 "general_operand"))) + (clobber (reg:CC VAX_PSL_REGNUM))]) + (parallel + [(set (reg:VAXccnz VAX_PSL_REGNUM) + (compare:VAXccnz + (and:VAXint (not:VAXint (match_dup 0)) + (match_operand:VAXint 3 "general_operand")) + (const_int 0))) + (set (match_operand:VAXint 2 "register_operand") + (and:VAXint (not:VAXint (match_dup 0)) + (match_dup 3)))])] + "peep2_reg_dead_p (2, operands[0]) && peep2_reg_dead_p (2, operands[2])" + [(set (reg:VAXccnz VAX_PSL_REGNUM) + (compare:VAXccnz + (and:VAXint (match_dup 1) + (match_dup 3)) + (const_int 0)))] + "") ;;- Bit set instructions. -(define_insn "ior<mode>3" +(define_insn_and_split "ior<mode>3" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g") (ior:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT") (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (ior:VAXint (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*ior<mode>3<ccn><ccnz><ccz>" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g") + (ior:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT") + (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "@ bis<VAXint:isfx>2 %2,%0 bis<VAXint:isfx>2 %1,%0 @@ -591,35 +1281,97 @@ ;;- xor instructions. -(define_insn "xor<mode>3" +(define_insn_and_split "xor<mode>3" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g") (xor:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT") (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (xor:VAXint (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*xor<mode>3<ccn><ccnz><ccz>" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g") + (xor:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT") + (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "@ xor<VAXint:isfx>2 %2,%0 xor<VAXint:isfx>2 %1,%0 xor<VAXint:isfx>3 %2,%1,%0") - -(define_insn "neg<mode>2" +(define_insn_and_split "neg<mode>2" [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g") (neg:VAXfp (match_operand:VAXfp 1 "general_operand" "gF")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (neg:VAXfp (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*neg<mode>2<fccn><fccnz><fccz>" + [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g") + (neg:VAXfp (match_operand:VAXfp 1 "general_operand" "gF"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "mneg<VAXfp:fsfx> %1,%0") -(define_insn "neg<mode>2" +(define_insn_and_split "neg<mode>2" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g") (neg:VAXint (match_operand:VAXint 1 "general_operand" "nrmT")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (neg:VAXint (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*neg<mode>2<ccn><ccnz><ccz>" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g") + (neg:VAXint (match_operand:VAXint 1 "general_operand" "nrmT"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "mneg<VAXint:isfx> %1,%0") -(define_insn "one_cmpl<mode>2" +(define_insn "*neg<mode>2_cc" + [(set (reg:CC VAX_PSL_REGNUM) + (compare:CC (const_int 0) + (neg:VAXint + (match_operand:VAXint 1 "general_operand" "0,nrmT")))) + (set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g") + (neg:VAXint (match_dup 1)))] + "reload_completed" + "mneg<VAXint:isfx> %1,%0") + +(define_insn_and_split "one_cmpl<mode>2" [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g") (not:VAXint (match_operand:VAXint 1 "general_operand" "nrmT")))] "" - "mcom<VAXint:isfx> %1,%0") + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (not:VAXint (match_dup 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") +(define_insn "*one_cmpl<mode>2<ccn><ccnz><ccz>" + [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g") + (not:VAXint (match_operand:VAXint 1 "general_operand" "nrmT"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" + "mcom<VAXint:isfx> %1,%0") ;; Arithmetic right shift on the VAX works by negating the shift count, ;; then emitting a right shift with the shift count negated. This means @@ -637,25 +1389,70 @@ operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2])); }") -(define_insn "" +(define_insn_and_split "*ashlnegsi3_const_int" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT") (match_operand:QI 2 "const_int_operand" "n")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (ashiftrt:SI (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*ashlnegsi3_const_int_2<ccn><ccnz><ccz>" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT") + (match_operand:QI 2 "const_int_operand" "n"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "ashl $%n2,%1,%0") -(define_insn "" +(define_insn_and_split "*ashlnegsi3" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT") (neg:QI (match_operand:QI 2 "general_operand" "g"))))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (ashiftrt:SI (match_dup 1) + (neg:QI (match_dup 2)))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*ashlnegsi3_2<ccn><ccnz><ccz>" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT") + (neg:QI (match_operand:QI 2 "general_operand" "g")))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "ashl %2,%1,%0") -(define_insn "ashlsi3" +(define_insn_and_split "ashlsi3" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (ashift:SI (match_operand:SI 1 "general_operand" "nrmT") (match_operand:QI 2 "general_operand" "g")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (ashift:SI (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*ashlsi3<ccn><ccnz><ccz>" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (ashift:SI (match_operand:SI 1 "general_operand" "nrmT") + (match_operand:QI 2 "general_operand" "g"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "* { if (operands[2] == const1_rtx && rtx_equal_p (operands[0], operands[1])) @@ -692,18 +1489,48 @@ operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2])); }") -(define_insn "ashldi3" +(define_insn_and_split "ashldi3" [(set (match_operand:DI 0 "nonimmediate_operand" "=g") (ashift:DI (match_operand:DI 1 "general_operand" "g") (match_operand:QI 2 "general_operand" "g")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (ashift:DI (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*ashldi3<ccn><ccnz><ccz>" + [(set (match_operand:DI 0 "nonimmediate_operand" "=g") + (ashift:DI (match_operand:DI 1 "general_operand" "g") + (match_operand:QI 2 "general_operand" "g"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "ashq %2,%D1,%0") -(define_insn "" +(define_insn_and_split "*ashlnegdi3" [(set (match_operand:DI 0 "nonimmediate_operand" "=g") (ashiftrt:DI (match_operand:DI 1 "general_operand" "g") (neg:QI (match_operand:QI 2 "general_operand" "g"))))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (ashiftrt:DI (match_dup 1) + (neg:QI (match_dup 2)))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*ashlnegdi3_2<ccn><ccnz><ccz>" + [(set (match_operand:DI 0 "nonimmediate_operand" "=g") + (ashiftrt:DI (match_operand:DI 1 "general_operand" "g") + (neg:QI (match_operand:QI 2 "general_operand" "g")))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "ashq %2,%D1,%0") ;; We used to have expand_shift handle logical right shifts by using extzv, @@ -738,146 +1565,300 @@ operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2])); }") -(define_insn "rotlsi3" +(define_insn_and_split "rotlsi3" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (rotate:SI (match_operand:SI 1 "general_operand" "nrmT") (match_operand:QI 2 "general_operand" "g")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (rotate:SI (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*rotlsi3<ccn><ccnz><ccz>" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (rotate:SI (match_operand:SI 1 "general_operand" "nrmT") + (match_operand:QI 2 "general_operand" "g"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "rotl %2,%1,%0") -(define_insn "" +(define_insn_and_split "*rotrsi3_const_int" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (rotatert:SI (match_operand:SI 1 "general_operand" "nrmT") (match_operand:QI 2 "const_int_operand" "n")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (rotatert:SI (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*rotrsi3_const_int_2<ccn><ccnz><ccz>" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (rotatert:SI (match_operand:SI 1 "general_operand" "nrmT") + (match_operand:QI 2 "const_int_operand" "n"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "rotl %R2,%1,%0") -(define_insn "" +(define_insn_and_split "*rotrnegsi3" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (rotatert:SI (match_operand:SI 1 "general_operand" "nrmT") (neg:QI (match_operand:QI 2 "general_operand" "g"))))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (rotatert:SI (match_dup 1) + (neg:QI (match_dup 2)))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*rotrnegsi3_2<ccn><ccnz><ccz>" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (rotatert:SI (match_operand:SI 1 "general_operand" "nrmT") + (neg:QI (match_operand:QI 2 "general_operand" "g")))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "rotl %2,%1,%0") -;This insn is probably slower than a multiply and an add. -;(define_insn "" -; [(set (match_operand:SI 0 "general_operand" "=g") -; (mult:SI (plus:SI (match_operand:SI 1 "general_operand" "g") -; (match_operand:SI 2 "general_operand" "g")) -; (match_operand:SI 3 "general_operand" "g")))] -; "" -; "index %1,$0x80000000,$0x7fffffff,%3,%2,%0") +;; This insn is probably slower than a multiply and an add. +;;(define_insn_and_split "*amulsi4" +;; [(set (match_operand:SI 0 "nonimmediate_operand" "=g") +;; (mult:SI (plus:SI (match_operand:SI 1 "general_operand" "g") +;; (match_operand:SI 2 "general_operand" "g")) +;; (match_operand:SI 3 "general_operand" "g")))] +;; "" +;; "#" +;; "reload_completed" +;; [(parallel +;; [(set (match_dup 0) +;; (mult:SI (plus:SI (match_dup 1) +;; (match_dup 2)) +;; (match_dup 3))) +;; (clobber (reg:CC VAX_PSL_REGNUM))])] +;; "") +;; +;;(define_insn "*amulsi4_2<ccn><ccnz><ccz>" +;; [(set (match_operand:SI 0 "nonimmediate_operand" "=g") +;; (mult:SI (plus:SI (match_operand:SI 1 "general_operand" "g") +;; (match_operand:SI 2 "general_operand" "g")) +;; (match_operand:SI 3 "general_operand" "g"))) +;; (clobber (reg:CC VAX_PSL_REGNUM))] +;; "reload_completed" +;; "index %1,$0x80000000,$0x7fffffff,%3,%2,%0") ;; Special cases of bit-field insns which we should ;; recognize in preference to the general case. -;; These handle aligned 8-bit and 16-bit fields, -;; which can usually be done with move instructions. +;; These handle aligned 8-bit and 16-bit fields +;; that can be done with move or convert instructions. -(define_insn "" - [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+ro") +(define_insn_and_split "*insv_aligned" + [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+ro") (match_operand:QI 1 "const_int_operand" "n") (match_operand:SI 2 "const_int_operand" "n")) (match_operand:SI 3 "general_operand" "g"))] - "(INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16) + "(INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16) && INTVAL (operands[2]) % INTVAL (operands[1]) == 0 && (!MEM_P (operands[0]) - || ! mode_dependent_address_p (XEXP (operands[0], 0), - MEM_ADDR_SPACE (operands[0])))" + || ((!flag_pic + || vax_acceptable_pic_operand_p (XEXP (operands[0], 0), + true, true)) + && !mode_dependent_address_p (XEXP (operands[0], 0), + MEM_ADDR_SPACE (operands[0])))) + && (!(REG_P (operands[0]) + || (SUBREG_P (operands[0]) && REG_P (SUBREG_REG (operands[0])))) + || INTVAL (operands[2]) == 0)" + "#" + "&& reload_completed" + [(parallel + [(set (zero_extract:SI (match_dup 0) + (match_dup 1) + (match_dup 2)) + (match_dup 3)) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*insv_aligned_2<ccn><ccnz><ccz>" + [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+ro") + (match_operand:QI 1 "const_int_operand" "n") + (match_operand:SI 2 "const_int_operand" "n")) + (match_operand:SI 3 "general_operand" "g")) + (clobber (reg:CC VAX_PSL_REGNUM))] + "(INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16) + && INTVAL (operands[2]) % INTVAL (operands[1]) == 0 + && (!MEM_P (operands[0]) + || ((!flag_pic + || vax_acceptable_pic_operand_p (XEXP (operands[0], 0), + true, true)) + && !mode_dependent_address_p (XEXP (operands[0], 0), + MEM_ADDR_SPACE (operands[0])))) + && (!(REG_P (operands[0]) + || (SUBREG_P (operands[0]) && REG_P (SUBREG_REG (operands[0])))) + || INTVAL (operands[2]) == 0) + && reload_completed" "* { - if (REG_P (operands[0])) - { - if (INTVAL (operands[2]) != 0) - return \"insv %3,%2,%1,%0\"; - } - else + if (!REG_P (operands[0])) operands[0] = adjust_address (operands[0], INTVAL (operands[1]) == 8 ? QImode : HImode, INTVAL (operands[2]) / 8); + else + gcc_assert (INTVAL (operands[2]) == 0); - CC_STATUS_INIT; if (INTVAL (operands[1]) == 8) return \"movb %3,%0\"; return \"movw %3,%0\"; }") -(define_insn "" +(define_insn_and_split "*extzv_aligned" [(set (match_operand:SI 0 "nonimmediate_operand" "=&g") - (zero_extract:SI (match_operand:SI 1 "register_operand" "ro") + (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro") (match_operand:QI 2 "const_int_operand" "n") (match_operand:SI 3 "const_int_operand" "n")))] "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) && INTVAL (operands[3]) % INTVAL (operands[2]) == 0 && (!MEM_P (operands[1]) - || ! mode_dependent_address_p (XEXP (operands[1], 0), - MEM_ADDR_SPACE (operands[1])))" + || ((!flag_pic + || vax_acceptable_pic_operand_p (XEXP (operands[1], 0), + true, true)) + && !mode_dependent_address_p (XEXP (operands[1], 0), + MEM_ADDR_SPACE (operands[1])))) + && (!(REG_P (operands[1]) + || (SUBREG_P (operands[1]) && REG_P (SUBREG_REG (operands[1])))) + || INTVAL (operands[3]) == 0)" + "#" + "&& reload_completed" + [(parallel + [(set (match_dup 0) + (zero_extract:SI (match_dup 1) + (match_dup 2) + (match_dup 3))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*extzv_aligned_2<ccn><ccnz><ccz>" + [(set (match_operand:SI 0 "nonimmediate_operand" "=&g") + (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro") + (match_operand:QI 2 "const_int_operand" "n") + (match_operand:SI 3 "const_int_operand" "n"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) + && INTVAL (operands[3]) % INTVAL (operands[2]) == 0 + && (!MEM_P (operands[1]) + || ((!flag_pic + || vax_acceptable_pic_operand_p (XEXP (operands[1], 0), + true, true)) + && !mode_dependent_address_p (XEXP (operands[1], 0), + MEM_ADDR_SPACE (operands[1])))) + && (!(REG_P (operands[1]) + || (SUBREG_P (operands[1]) && REG_P (SUBREG_REG (operands[1])))) + || INTVAL (operands[3]) == 0) + && reload_completed" "* { - if (REG_P (operands[1])) - { - if (INTVAL (operands[3]) != 0) - return \"extzv %3,%2,%1,%0\"; - } - else + if (!REG_P (operands[1])) operands[1] = adjust_address (operands[1], INTVAL (operands[2]) == 8 ? QImode : HImode, INTVAL (operands[3]) / 8); + else + gcc_assert (INTVAL (operands[3]) == 0); if (INTVAL (operands[2]) == 8) return \"movzbl %1,%0\"; return \"movzwl %1,%0\"; }") -(define_insn "" +(define_insn_and_split "*extv_aligned" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") - (sign_extract:SI (match_operand:SI 1 "register_operand" "ro") + (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro") (match_operand:QI 2 "const_int_operand" "n") (match_operand:SI 3 "const_int_operand" "n")))] "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) && INTVAL (operands[3]) % INTVAL (operands[2]) == 0 && (!MEM_P (operands[1]) - || ! mode_dependent_address_p (XEXP (operands[1], 0), - MEM_ADDR_SPACE (operands[1])))" + || ((!flag_pic + || vax_acceptable_pic_operand_p (XEXP (operands[1], 0), + true, true)) + && !mode_dependent_address_p (XEXP (operands[1], 0), + MEM_ADDR_SPACE (operands[1])))) + && (!(REG_P (operands[1]) + || (SUBREG_P (operands[1]) && REG_P (SUBREG_REG (operands[1])))) + || INTVAL (operands[3]) == 0)" + "#" + "&& reload_completed" + [(parallel + [(set (match_dup 0) + (sign_extract:SI (match_dup 1) + (match_dup 2) + (match_dup 3))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*extv_aligned_2<ccn><ccnz><ccz>" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro") + (match_operand:QI 2 "const_int_operand" "n") + (match_operand:SI 3 "const_int_operand" "n"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) + && INTVAL (operands[3]) % INTVAL (operands[2]) == 0 + && (!MEM_P (operands[1]) + || ((!flag_pic + || vax_acceptable_pic_operand_p (XEXP (operands[1], 0), + true, true)) + && !mode_dependent_address_p (XEXP (operands[1], 0), + MEM_ADDR_SPACE (operands[1])))) + && (!(REG_P (operands[1]) + || (SUBREG_P (operands[1]) && REG_P (SUBREG_REG (operands[1])))) + || INTVAL (operands[3]) == 0) + && reload_completed" "* { - if (REG_P (operands[1])) - { - if (INTVAL (operands[3]) != 0) - return \"extv %3,%2,%1,%0\"; - } - else + if (!REG_P (operands[1])) operands[1] = adjust_address (operands[1], INTVAL (operands[2]) == 8 ? QImode : HImode, INTVAL (operands[3]) / 8); + else + gcc_assert (INTVAL (operands[3]) == 0); if (INTVAL (operands[2]) == 8) return \"cvtbl %1,%0\"; return \"cvtwl %1,%0\"; }") -;; Register-only SImode cases of bit-field insns. +;; Register and non-offsettable-memory SImode cases of bit-field insns. -(define_insn "" - [(set (cc0) - (compare - (sign_extract:SI (match_operand:SI 0 "register_operand" "r") +(define_insn "*cmpv_<mode>" + [(set (reg:VAXcc VAX_PSL_REGNUM) + (compare:VAXcc + (sign_extract:SI (match_operand:SI 0 "nonimmediate_operand" "ro") (match_operand:QI 1 "general_operand" "g") (match_operand:SI 2 "general_operand" "nrmT")) (match_operand:SI 3 "general_operand" "nrmT")))] - "" + "reload_completed" "cmpv %2,%1,%0,%3") -(define_insn "" - [(set (cc0) - (compare - (zero_extract:SI (match_operand:SI 0 "register_operand" "r") +(define_insn "*cmpzv_<mode>" + [(set (reg:VAXcc VAX_PSL_REGNUM) + (compare:VAXcc + (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "ro") (match_operand:QI 1 "general_operand" "g") (match_operand:SI 2 "general_operand" "nrmT")) (match_operand:SI 3 "general_operand" "nrmT")))] - "" + "reload_completed" "cmpzv %2,%1,%0,%3") ;; When the field position and size are constant and the destination @@ -885,12 +1866,29 @@ ;; by a bicl or sign extension. Because we might end up choosing ext[z]v ;; anyway, we can't allow immediate values for the primary source operand. -(define_insn "" +(define_insn_and_split "*extv_non_const" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") - (sign_extract:SI (match_operand:SI 1 "register_operand" "ro") + (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro") (match_operand:QI 2 "general_operand" "g") (match_operand:SI 3 "general_operand" "nrmT")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (sign_extract:SI (match_dup 1) + (match_dup 2) + (match_dup 3))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*extv_non_const_2<ccn><ccnz><ccz>" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro") + (match_operand:QI 2 "general_operand" "g") + (match_operand:SI 3 "general_operand" "nrmT"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "* { if (! CONST_INT_P (operands[3]) || ! CONST_INT_P (operands[2]) @@ -902,12 +1900,29 @@ return \"rotl %R3,%1,%0\;cvtwl %0,%0\"; }") -(define_insn "" +(define_insn_and_split "*extzv_non_const" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") - (zero_extract:SI (match_operand:SI 1 "register_operand" "ro") + (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro") (match_operand:QI 2 "general_operand" "g") (match_operand:SI 3 "general_operand" "nrmT")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (zero_extract:SI (match_dup 1) + (match_dup 2) + (match_dup 3))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*extzv_non_const_2<ccn><ccnz><ccz>" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro") + (match_operand:QI 2 "general_operand" "g") + (match_operand:SI 3 "general_operand" "nrmT"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "* { if (! CONST_INT_P (operands[3]) || ! CONST_INT_P (operands[2]) @@ -928,32 +1943,57 @@ ;; nonimmediate_operand is used to make sure that mode-ambiguous cases ;; don't match these (and therefore match the cases above instead). -(define_insn "" - [(set (cc0) - (compare +(define_insn "*cmpv_2_<mode>" + [(set (reg:VAXcc VAX_PSL_REGNUM) + (compare:VAXcc (sign_extract:SI (match_operand:QI 0 "memory_operand" "m") (match_operand:QI 1 "general_operand" "g") (match_operand:SI 2 "general_operand" "nrmT")) (match_operand:SI 3 "general_operand" "nrmT")))] - "" + "reload_completed" "cmpv %2,%1,%0,%3") -(define_insn "" - [(set (cc0) - (compare - (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "rm") +(define_insn "*cmpzv_2_<mode>" + [(set (reg:VAXcc VAX_PSL_REGNUM) + (compare:VAXcc + (zero_extract:SI (match_operand:QI 0 "memory_operand" "m") (match_operand:QI 1 "general_operand" "g") (match_operand:SI 2 "general_operand" "nrmT")) (match_operand:SI 3 "general_operand" "nrmT")))] - "" + "reload_completed" "cmpzv %2,%1,%0,%3") -(define_insn "extv" +(define_expand "extv" + [(set (match_operand:SI 0 "general_operand" "") + (sign_extract:SI (match_operand:SI 1 "general_operand" "") + (match_operand:QI 2 "general_operand" "") + (match_operand:SI 3 "general_operand" "")))] + "" + "") + +(define_insn_and_split "*extv" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (sign_extract:SI (match_operand:QI 1 "memory_operand" "m") (match_operand:QI 2 "general_operand" "g") (match_operand:SI 3 "general_operand" "nrmT")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (sign_extract:SI (match_dup 1) + (match_dup 2) + (match_dup 3))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*extv_2<ccn><ccnz><ccz>" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (sign_extract:SI (match_operand:QI 1 "memory_operand" "m") + (match_operand:QI 2 "general_operand" "g") + (match_operand:SI 3 "general_operand" "nrmT"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "* { if (!REG_P (operands[0]) || !CONST_INT_P (operands[2]) @@ -978,12 +2018,29 @@ "" "") -(define_insn "" +(define_insn_and_split "*extzv" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (zero_extract:SI (match_operand:QI 1 "memory_operand" "m") (match_operand:QI 2 "general_operand" "g") (match_operand:SI 3 "general_operand" "nrmT")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (zero_extract:SI (match_dup 1) + (match_dup 2) + (match_dup 3))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*extzv_2<ccn><ccnz><ccz>" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (zero_extract:SI (match_operand:QI 1 "memory_operand" "m") + (match_operand:QI 2 "general_operand" "g") + (match_operand:SI 3 "general_operand" "nrmT"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "* { if (!REG_P (operands[0]) || !CONST_INT_P (operands[2]) @@ -1023,6 +2080,28 @@ return \"rotl %R3,%1,%0\;bicl2 %M2,%0\"; }") +;; Combine EXTV/CMPL and EXTZV/CMPL sequences where the output of +;; extraction is used for the comparison only into CMPV and CMPZV +;; respectively. +(define_peephole2 + [(parallel + [(set (match_operand:SI 0 "register_operand") + (any_extract:SI (match_operand 1 "general_operand") + (match_operand:QI 2 "general_operand") + (match_operand:SI 3 "general_operand"))) + (clobber (reg:CC VAX_PSL_REGNUM))]) + (set (reg:VAXcc VAX_PSL_REGNUM) + (compare:VAXcc (match_dup 0) + (match_operand:SI 4 "general_operand")))] + "peep2_reg_dead_p (2, operands[0])" + [(set (reg:VAXcc VAX_PSL_REGNUM) + (compare:VAXcc + (any_extract:SI (match_dup 1) + (match_dup 2) + (match_dup 3)) + (match_dup 4)))] + "") + (define_expand "insv" [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "") (match_operand:QI 1 "general_operand" "") @@ -1031,8 +2110,9 @@ "" "") -(define_insn "" - [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+g") +;; This one actually doesn't change CC. +(define_insn "*insv" + [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+m") (match_operand:QI 1 "general_operand" "g") (match_operand:SI 2 "general_operand" "nrmT")) (match_operand:SI 3 "general_operand" "nrmT"))] @@ -1062,8 +2142,9 @@ return \"insv %3,%2,%1,%0\"; }") -(define_insn "" - [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") +;; This one actually doesn't change CC. +(define_insn "*insv_2" + [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+ro") (match_operand:QI 1 "general_operand" "g") (match_operand:SI 2 "general_operand" "nrmT")) (match_operand:SI 3 "general_operand" "nrmT"))] @@ -1080,49 +2161,89 @@ ;; Conditional jumps (define_expand "cbranch<mode>4" - [(set (cc0) - (compare (match_operand:VAXint 1 "nonimmediate_operand" "") - (match_operand:VAXint 2 "general_operand" ""))) + [(set (pc) + (if_then_else + (match_operator 0 "ordered_comparison_operator" + [(match_operand:VAXint 1 "general_operand" "") + (match_operand:VAXint 2 "general_operand" "")]) + (label_ref (match_operand 3 "" "")) + (pc)))] + "" + "") + +(define_insn_and_split "*cbranch<VAXint:mode>4_<VAXcc:mode>" + [(set (pc) + (if_then_else + (match_operator 0 "vax_<cc>_comparison_operator" + [(match_operand:VAXint 1 "general_operand" "nrmT") + (match_operand:VAXint 2 "general_operand" "nrmT")]) + (label_ref (match_operand 3 "" "")) + (pc)))] + "" + "#" + "reload_completed" + [(set (reg:VAXcc VAX_PSL_REGNUM) + (compare:VAXcc (match_dup 1) (match_dup 2))) (set (pc) - (if_then_else - (match_operator 0 "ordered_comparison_operator" [(cc0) - (const_int 0)]) - (label_ref (match_operand 3 "" "")) - (pc)))] - "") + (if_then_else + (match_op_dup 0 [(reg:VAXcc VAX_PSL_REGNUM) + (const_int 0)]) + (label_ref (match_operand 3 "" "")) + (pc)))] + "") (define_expand "cbranch<mode>4" - [(set (cc0) - (compare (match_operand:VAXfp 1 "general_operand" "") - (match_operand:VAXfp 2 "general_operand" ""))) + [(set (pc) + (if_then_else + (match_operator 0 "ordered_comparison_operator" + [(match_operand:VAXfp 1 "general_operand" "") + (match_operand:VAXfp 2 "general_operand" "")]) + (label_ref (match_operand 3 "" "")) + (pc)))] + "" + "") + +(define_insn_and_split "*cbranch<VAXfp:mode>4_<VAXccnz:mode>" + [(set (pc) + (if_then_else + (match_operator 0 "vax_<cc>_comparison_operator" + [(match_operand:VAXfp 1 "general_operand" "gF") + (match_operand:VAXfp 2 "general_operand" "gF")]) + (label_ref (match_operand 3 "" "")) + (pc)))] + "" + "#" + "reload_completed" + [(set (reg:VAXccnz VAX_PSL_REGNUM) + (compare:VAXccnz (match_dup 1) (match_dup 2))) (set (pc) - (if_then_else - (match_operator 0 "ordered_comparison_operator" [(cc0) - (const_int 0)]) - (label_ref (match_operand 3 "" "")) - (pc)))] - "") - -(define_insn "*branch" + (if_then_else + (match_op_dup 0 [(reg:VAXccnz VAX_PSL_REGNUM) + (const_int 0)]) + (label_ref (match_operand 3 "" "")) + (pc)))] + "") + +(define_insn "*branch_<mode>" [(set (pc) - (if_then_else (match_operator 0 "ordered_comparison_operator" - [(cc0) + (if_then_else (match_operator 0 "vax_<cc>_comparison_operator" + [(reg:VAXcc VAX_PSL_REGNUM) (const_int 0)]) (label_ref (match_operand 1 "" "")) (pc)))] - "" - "j%c0 %l1") + "reload_completed" + "j%k0 %l1") ;; Recognize reversed jumps. -(define_insn "*branch_reversed" +(define_insn "*branch_<mode>_reversed" [(set (pc) - (if_then_else (match_operator 0 "ordered_comparison_operator" - [(cc0) + (if_then_else (match_operator 0 "vax_<cc>_comparison_operator" + [(reg:VAXcc VAX_PSL_REGNUM) (const_int 0)]) (pc) (label_ref (match_operand 1 "" ""))))] - "" - "j%C0 %l1") ; %C0 negates condition + "reload_completed" + "j%K0 %l1") ; %K0 negates condition ;; Recognize jbs, jlbs, jbc and jlbc instructions. Note that the operand ;; of jlbs and jlbc insns are SImode in the hardware. However, if it is @@ -1191,7 +2312,7 @@ ;; Normal sob insns. -(define_insn "" +(define_insn_and_split "*jsobgtr" [(set (pc) (if_then_else (gt (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g") @@ -1203,9 +2324,38 @@ (plus:SI (match_dup 0) (const_int -1)))] "!TARGET_UNIX_ASM" + "#" + "&& reload_completed" + [(parallel + [(set (pc) + (if_then_else + (gt (plus:SI (match_dup 0) + (const_int -1)) + (const_int 0)) + (label_ref (match_dup 1)) + (pc))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int -1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*jsobgtr_2" + [(set (pc) + (if_then_else + (gt (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g") + (const_int -1)) + (const_int 0)) + (label_ref (match_operand 1 "" "")) + (pc))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int -1))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "!TARGET_UNIX_ASM && reload_completed" "jsobgtr %0,%l1") -(define_insn "" +(define_insn_and_split "*jsobgeq" [(set (pc) (if_then_else (ge (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g") @@ -1217,10 +2367,39 @@ (plus:SI (match_dup 0) (const_int -1)))] "!TARGET_UNIX_ASM" + "#" + "&& reload_completed" + [(parallel + [(set (pc) + (if_then_else + (ge (plus:SI (match_dup 0) + (const_int -1)) + (const_int 0)) + (label_ref (match_dup 1)) + (pc))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int -1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*jsobgeq_2" + [(set (pc) + (if_then_else + (ge (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g") + (const_int -1)) + (const_int 0)) + (label_ref (match_operand 1 "" "")) + (pc))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int -1))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "!TARGET_UNIX_ASM && reload_completed" "jsobgeq %0,%l1") ;; Normal aob insns. Define a version for when operands[1] is a constant. -(define_insn "" +(define_insn_and_split "*jaoblss" [(set (pc) (if_then_else (lt (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g") @@ -1232,9 +2411,38 @@ (plus:SI (match_dup 0) (const_int 1)))] "!TARGET_UNIX_ASM" + "#" + "&& reload_completed" + [(parallel + [(set (pc) + (if_then_else + (lt (plus:SI (match_dup 0) + (const_int 1)) + (match_dup 1)) + (label_ref (match_dup 2)) + (pc))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*jaoblss_2" + [(set (pc) + (if_then_else + (lt (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g") + (const_int 1)) + (match_operand:SI 1 "general_operand" "nrmT")) + (label_ref (match_operand 2 "" "")) + (pc))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int 1))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "!TARGET_UNIX_ASM && reload_completed" "jaoblss %1,%0,%l2") -(define_insn "" +(define_insn_and_split "*jaoblss_const" [(set (pc) (if_then_else (lt (match_operand:SI 0 "nonimmediate_operand" "+g") @@ -1245,9 +2453,36 @@ (plus:SI (match_dup 0) (const_int 1)))] "!TARGET_UNIX_ASM && CONST_INT_P (operands[1])" + "#" + "&& reload_completed" + [(parallel + [(set (pc) + (if_then_else + (lt (match_dup 0) + (match_dup 1)) + (label_ref (match_dup 2)) + (pc))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*jaoblss_const_2" + [(set (pc) + (if_then_else + (lt (match_operand:SI 0 "nonimmediate_operand" "+g") + (match_operand:SI 1 "general_operand" "nrmT")) + (label_ref (match_operand 2 "" "")) + (pc))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int 1))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "!TARGET_UNIX_ASM && CONST_INT_P (operands[1]) && reload_completed" "jaoblss %P1,%0,%l2") -(define_insn "" +(define_insn_and_split "*jaobleq" [(set (pc) (if_then_else (le (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g") @@ -1259,9 +2494,38 @@ (plus:SI (match_dup 0) (const_int 1)))] "!TARGET_UNIX_ASM" + "#" + "&& reload_completed" + [(parallel + [(set (pc) + (if_then_else + (le (plus:SI (match_dup 0) + (const_int 1)) + (match_dup 1)) + (label_ref (match_dup 2)) + (pc))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*jaobleq_2" + [(set (pc) + (if_then_else + (le (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g") + (const_int 1)) + (match_operand:SI 1 "general_operand" "nrmT")) + (label_ref (match_operand 2 "" "")) + (pc))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int 1))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "!TARGET_UNIX_ASM && reload_completed" "jaobleq %1,%0,%l2") -(define_insn "" +(define_insn_and_split "*jaobleq_const" [(set (pc) (if_then_else (le (match_operand:SI 0 "nonimmediate_operand" "+g") @@ -1272,12 +2536,39 @@ (plus:SI (match_dup 0) (const_int 1)))] "!TARGET_UNIX_ASM && CONST_INT_P (operands[1])" + "#" + "&& reload_completed" + [(parallel + [(set (pc) + (if_then_else + (le (match_dup 0) + (match_dup 1)) + (label_ref (match_dup 2)) + (pc))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int 1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*jaobleq_const_2" + [(set (pc) + (if_then_else + (le (match_operand:SI 0 "nonimmediate_operand" "+g") + (match_operand:SI 1 "general_operand" "nrmT")) + (label_ref (match_operand 2 "" "")) + (pc))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int 1))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "!TARGET_UNIX_ASM && CONST_INT_P (operands[1]) && reload_completed" "jaobleq %P1,%0,%l2") ;; Something like a sob insn, but compares against -1. ;; This finds `while (foo--)' which was changed to `while (--foo != -1)'. -(define_insn "" +(define_insn_and_split "*jsobneq_minus_one" [(set (pc) (if_then_else (ne (match_operand:SI 0 "nonimmediate_operand" "+g") @@ -1288,6 +2579,33 @@ (plus:SI (match_dup 0) (const_int -1)))] "" + "#" + "reload_completed" + [(parallel + [(set (pc) + (if_then_else + (ne (match_dup 0) + (const_int 0)) + (label_ref (match_dup 1)) + (pc))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int -1))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*jsobneq_minus_one_2" + [(set (pc) + (if_then_else + (ne (match_operand:SI 0 "nonimmediate_operand" "+g") + (const_int 0)) + (label_ref (match_operand 1 "" "")) + (pc))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int -1))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "decl %0\;jgequ %l1") (define_expand "call_pop" @@ -1514,40 +2832,127 @@ ;; This insn is a bit of a lier. It actually falls through if no case ;; matches. But, we prevent that from ever happening by emitting a jump ;; before this, see the define_expand above. -(define_insn "casesi1" +(define_insn_and_split "casesi1" [(match_operand:SI 1 "const_int_operand" "n") (set (pc) (plus:SI (sign_extend:SI - (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "general_operand" "nrmT") - (const_int 2)) - (pc)))) + (mem:HI (plus:SI + (mult:SI + (match_operand:SI 0 "general_operand" "nrmT") + (const_int 2)) + (pc)))) (label_ref:SI (match_operand 2 "" ""))))] "" + "#" + "reload_completed" + [(parallel + [(match_dup 1) + (set (pc) + (plus:SI (sign_extend:SI + (mem:HI (plus:SI + (mult:SI + (match_dup 0) + (const_int 2)) + (pc)))) + (label_ref:SI (match_dup 2)))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*casesi1" + [(match_operand:SI 1 "const_int_operand" "n") + (set (pc) + (plus:SI (sign_extend:SI + (mem:HI (plus:SI + (mult:SI + (match_operand:SI 0 "general_operand" "nrmT") + (const_int 2)) + (pc)))) + (label_ref:SI (match_operand 2 "" "")))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "casel %0,$0,%1") -(define_insn "pushextsym" +(define_insn_and_split "*pushsym" [(set (match_operand:SI 0 "push_operand" "=g") - (match_operand:SI 1 "external_symbolic_operand" "i"))] - "" + (match_operand:SI 1 "pic_symbolic_operand" "A"))] + "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (match_dup 1)) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*pushsym_2<ccn><ccnz><ccz>" + [(set (match_operand:SI 0 "push_operand" "=g") + (match_operand:SI 1 "pic_symbolic_operand" "A")) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "pushab %a1") -(define_insn "movextsym" +(define_insn_and_split "*movsym" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") - (match_operand:SI 1 "external_symbolic_operand" "i"))] - "" + (match_operand:SI 1 "pic_symbolic_operand" "A"))] + "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (match_dup 1)) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*movsym_2<ccn><ccnz><ccz>" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (match_operand:SI 1 "pic_symbolic_operand" "A")) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "movab %a1,%0") -(define_insn "pushlclsym" +(define_insn_and_split "*pushsymreg" [(set (match_operand:SI 0 "push_operand" "=g") - (match_operand:SI 1 "local_symbolic_operand" "i"))] - "" - "pushab %a1") + (plus:SI (match_operand:SI 1 "register_operand" "%r") + (match_operand:SI 2 "pic_symbolic_operand" "A")))] + "flag_pic" + "#" + "&& reload_completed" + [(parallel + [(set (match_dup 0) + (plus:SI (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") -(define_insn "movlclsym" +(define_insn "*pushsymreg_2<ccn><ccnz><ccz>" + [(set (match_operand:SI 0 "push_operand" "=g") + (plus:SI (match_operand:SI 1 "register_operand" "%r") + (match_operand:SI 2 "pic_symbolic_operand" "A"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "flag_pic && reload_completed" + "pushab %a2[%1]") + +(define_insn_and_split "*movsymreg" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") - (match_operand:SI 1 "local_symbolic_operand" "i"))] - "" - "movab %a1,%0") + (plus:SI (match_operand:SI 1 "register_operand" "%r") + (match_operand:SI 2 "pic_symbolic_operand" "A")))] + "flag_pic" + "#" + "&& reload_completed" + [(parallel + [(set (match_dup 0) + (plus:SI (match_dup 1) + (match_dup 2))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*movsymreg_2<ccn><ccnz><ccz>" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (plus:SI (match_operand:SI 1 "register_operand" "%r") + (match_operand:SI 2 "pic_symbolic_operand" "A"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "flag_pic && reload_completed" + "movab %a2[%1],%0") ;;- load or push effective address ;; These come after the move and add/sub patterns @@ -1557,28 +2962,80 @@ ;; It does not work to use constraints to distinguish pushes from moves, ;; because < matches any autodecrement, not just a push. -(define_insn "pushaddr<mode>" +(define_insn_and_split "pushaddr<mode>" [(set (match_operand:SI 0 "push_operand" "=g") (match_operand:VAXintQHSD 1 "address_operand" "p"))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (match_dup 1)) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*pushaddr<mode><ccn><ccnz><ccz>" + [(set (match_operand:SI 0 "push_operand" "=g") + (match_operand:VAXintQHSD 1 "address_operand" "p")) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "pusha<VAXintQHSD:isfx> %a1") -(define_insn "movaddr<mode>" +(define_insn_and_split "movaddr<mode>" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (match_operand:VAXintQHSD 1 "address_operand" "p"))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (match_dup 1)) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*movaddr<mode><ccn><ccnz><ccz>" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (match_operand:VAXintQHSD 1 "address_operand" "p")) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "mova<VAXintQHSD:isfx> %a1,%0") -(define_insn "pushaddr<mode>" +(define_insn_and_split "pushaddr<mode>" [(set (match_operand:SI 0 "push_operand" "=g") (match_operand:VAXfp 1 "address_operand" "p"))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (match_dup 1)) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*pushaddr<mode><ccn><ccnz><ccz>" + [(set (match_operand:SI 0 "push_operand" "=g") + (match_operand:VAXfp 1 "address_operand" "p")) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "pusha<VAXfp:fsfx> %a1") -(define_insn "movaddr<mode>" +(define_insn_and_split "movaddr<mode>" [(set (match_operand:SI 0 "nonimmediate_operand" "=g") (match_operand:VAXfp 1 "address_operand" "p"))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (match_dup 1)) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*movaddr<mode>" + [(set (match_operand:SI 0 "nonimmediate_operand" "=g") + (match_operand:VAXfp 1 "address_operand" "p")) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "mova<VAXfp:fsfx> %a1,%0") ;; These used to be peepholes, but it is more straightforward to do them @@ -1594,12 +3051,30 @@ ;; with other operands constant. This is what the combiner converts the ;; above sequences to before attempting to recognize the new insn. -(define_insn "" +(define_insn_and_split "*andashlnegsi4" [(set (match_operand:SI 0 "nonimmediate_operand" "=ro") (and:SI (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT") (match_operand:QI 2 "const_int_operand" "n")) (match_operand:SI 3 "const_int_operand" "n")))] "(INTVAL (operands[3]) & ~((1 << (32 - INTVAL (operands[2]))) - 1)) == 0" + "#" + "&& reload_completed" + [(parallel + [(set (match_dup 0) + (and:SI (ashiftrt:SI (match_dup 1) + (match_dup 2)) + (match_dup 3))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*andashlnegsi4_2<ccn><ccnz><ccz>" + [(set (match_operand:SI 0 "nonimmediate_operand" "=ro") + (and:SI (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT") + (match_operand:QI 2 "const_int_operand" "n")) + (match_operand:SI 3 "const_int_operand" "n"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "(INTVAL (operands[3]) & ~((1 << (32 - INTVAL (operands[2]))) - 1)) == 0 + && reload_completed" "* { unsigned long mask1 = INTVAL (operands[3]); @@ -1616,12 +3091,29 @@ ;; bits that the ashl would anyways, in which case it should have been ;; optimized away. -(define_insn "" +(define_insn_and_split "*andashlsi4" [(set (match_operand:SI 0 "nonimmediate_operand" "=ro") (and:SI (ashift:SI (match_operand:SI 1 "general_operand" "nrmT") (match_operand:QI 2 "const_int_operand" "n")) (match_operand:SI 3 "const_int_operand" "n")))] "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) + (and:SI (ashift:SI (match_dup 1) + (match_dup 2)) + (match_dup 3))) + (clobber (reg:CC VAX_PSL_REGNUM))])] + "") + +(define_insn "*andashlsi4_2<ccn><ccnz><ccz>" + [(set (match_operand:SI 0 "nonimmediate_operand" "=ro") + (and:SI (ashift:SI (match_operand:SI 1 "general_operand" "nrmT") + (match_operand:QI 2 "const_int_operand" "n")) + (match_operand:SI 3 "const_int_operand" "n"))) + (clobber (reg:CC VAX_PSL_REGNUM))] + "reload_completed" "* { operands[3] @@ -1660,3 +3152,5 @@ emit_barrier (); DONE; }) + +(include "builtins.md") |