aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2020-12-07 10:45:52 -0800
committerIan Lance Taylor <iant@golang.org>2020-12-07 10:45:52 -0800
commit45c32be1f96ace25b66c34a84818dc5e07e9d516 (patch)
tree2a6658e3df17c11dd8d74d9c7403c9bc69678010 /gcc/config
parent945ae3ab27757d3261d99446f96105c5ebe70247 (diff)
parentb737b70fad398728f6006e8397d1bb31ccea4ce7 (diff)
downloadgcc-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.c5
-rw-r--r--gcc/config/i386/i386-c.c7
-rw-r--r--gcc/config/i386/i386-features.c3
-rw-r--r--gcc/config/i386/i386-options.c4
-rw-r--r--gcc/config/i386/i386.c5
-rw-r--r--gcc/config/i386/i386.h2
-rw-r--r--gcc/config/i386/i386.md8
-rw-r--r--gcc/config/i386/x86-tune-sched.c2
-rw-r--r--gcc/config/i386/x86-tune.def2
-rw-r--r--gcc/config/i386/znver1.md353
-rw-r--r--gcc/config/pdp11/pdp11.md4
-rw-r--r--gcc/config/rs6000/xcoff.h4
-rw-r--r--gcc/config/s390/s390.c2
-rw-r--r--gcc/config/vax/builtins.md269
-rw-r--r--gcc/config/vax/constraints.md4
-rw-r--r--gcc/config/vax/elf.h13
-rw-r--r--gcc/config/vax/netbsd-elf.h4
-rw-r--r--gcc/config/vax/predicates.md70
-rw-r--r--gcc/config/vax/vax-modes.def11
-rw-r--r--gcc/config/vax/vax-protos.h4
-rw-r--r--gcc/config/vax/vax.c353
-rw-r--r--gcc/config/vax/vax.h41
-rw-r--r--gcc/config/vax/vax.md2034
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")