aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMaxim Kuvyrkov <maxim@codesourcery.com>2012-07-21 00:01:40 +0000
committerMaxim Kuvyrkov <mkuvyrkov@gcc.gnu.org>2012-07-21 00:01:40 +0000
commit3088716e20615caba1e82abd8f7cf79d1a73f9ca (patch)
tree1e9f6f349a379aa72be1a2ea9c28a1aaff156eb6 /gcc
parentc1515facff18630fbd833b10fff9c742d5b371f3 (diff)
downloadgcc-3088716e20615caba1e82abd8f7cf79d1a73f9ca.zip
gcc-3088716e20615caba1e82abd8f7cf79d1a73f9ca.tar.gz
gcc-3088716e20615caba1e82abd8f7cf79d1a73f9ca.tar.bz2
mips.md (define_attr sync_*): Move before "type".
* config/mips/mips.md (define_attr sync_*): Move before "type". (define_attr "type"): New values "atomic" and "syncloop". * config/mips/sync.md (atomic_exchange<mode>, atomic_fetch_add<mode>): Set "type" attribute. * config/mips/generic.md (generic_atomic, generic_syncloop): New reservations. * gcc/config/mips/10000.md, gcc/config/mips/20kc.md, * gcc/config/mips/24k.md, gcc/config/mips/4130.md, * gcc/config/mips/4k.md, gcc/config/mips/5400.md, * gcc/config/mips/5500.md, gcc/config/mips/5k.md, * gcc/config/mips/7000.md, gcc/config/mips/74k.md, * gcc/config/mips/9000.md, gcc/config/mips/loongson2ef.md, * gcc/config/mips/loongson3a.md, gcc/config/mips/octeon.md, * gcc/config/mips/sb1.md, gcc/config/mips/sr71k.md, * gcc/config/mips/xlr.md: Handle "atomic" and "syncloop" types. From-SVN: r189734
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog18
-rw-r--r--gcc/config/mips/10000.md2
-rw-r--r--gcc/config/mips/20kc.md2
-rw-r--r--gcc/config/mips/24k.md2
-rw-r--r--gcc/config/mips/4130.md2
-rw-r--r--gcc/config/mips/4k.md2
-rw-r--r--gcc/config/mips/5400.md2
-rw-r--r--gcc/config/mips/5500.md2
-rw-r--r--gcc/config/mips/5k.md2
-rw-r--r--gcc/config/mips/7000.md2
-rw-r--r--gcc/config/mips/74k.md2
-rw-r--r--gcc/config/mips/9000.md2
-rw-r--r--gcc/config/mips/generic.md16
-rw-r--r--gcc/config/mips/loongson2ef.md2
-rw-r--r--gcc/config/mips/loongson3a.md2
-rw-r--r--gcc/config/mips/mips.md108
-rw-r--r--gcc/config/mips/octeon.md2
-rw-r--r--gcc/config/mips/sb1.md2
-rw-r--r--gcc/config/mips/sr71k.md2
-rw-r--r--gcc/config/mips/sync.md6
-rw-r--r--gcc/config/mips/xlr.md2
21 files changed, 111 insertions, 71 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5b8b210..34c9ac6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,21 @@
+2012-07-20 Maxim Kuvyrkov <maxim@codesourcery.com>
+
+ * config/mips/mips.md (define_attr sync_*): Move before "type".
+ (define_attr "type"): New values "atomic" and "syncloop".
+ * config/mips/sync.md (atomic_exchange<mode>, atomic_fetch_add<mode>):
+ Set "type" attribute.
+ * config/mips/generic.md (generic_atomic, generic_syncloop):
+ New reservations.
+ * gcc/config/mips/10000.md, gcc/config/mips/20kc.md,
+ * gcc/config/mips/24k.md, gcc/config/mips/4130.md,
+ * gcc/config/mips/4k.md, gcc/config/mips/5400.md,
+ * gcc/config/mips/5500.md, gcc/config/mips/5k.md,
+ * gcc/config/mips/7000.md, gcc/config/mips/74k.md,
+ * gcc/config/mips/9000.md, gcc/config/mips/loongson2ef.md,
+ * gcc/config/mips/loongson3a.md, gcc/config/mips/octeon.md,
+ * gcc/config/mips/sb1.md, gcc/config/mips/sr71k.md,
+ * gcc/config/mips/xlr.md: Handle "atomic" and "syncloop" types.
+
2012-07-20 Oleg Endo <olegendo@gcc.gnu.org>
* config/sh/sh.md: Group and sort shift related patterns.
diff --git a/gcc/config/mips/10000.md b/gcc/config/mips/10000.md
index 589cd1b..ae376b0 100644
--- a/gcc/config/mips/10000.md
+++ b/gcc/config/mips/10000.md
@@ -247,5 +247,5 @@
;; Handle unknown/multi insns here (this is a guess).
(define_insn_reservation "r10k_unknown" 1
(and (eq_attr "cpu" "r10000")
- (eq_attr "type" "unknown,multi"))
+ (eq_attr "type" "unknown,multi,atomic,syncloop"))
"r10k_alu1 + r10k_alu2")
diff --git a/gcc/config/mips/20kc.md b/gcc/config/mips/20kc.md
index 6581f5d..5c0088c 100644
--- a/gcc/config/mips/20kc.md
+++ b/gcc/config/mips/20kc.md
@@ -280,5 +280,5 @@
;; Force single-dispatch for unknown or multi.
(define_insn_reservation "r20kc_unknown" 1
(and (eq_attr "cpu" "20kc")
- (eq_attr "type" "unknown,multi"))
+ (eq_attr "type" "unknown,multi,atomic,syncloop"))
"r20kc_single_dispatch")
diff --git a/gcc/config/mips/24k.md b/gcc/config/mips/24k.md
index 1d701e7..bc4b45b 100644
--- a/gcc/config/mips/24k.md
+++ b/gcc/config/mips/24k.md
@@ -149,7 +149,7 @@
;; scheduling via log links, but not used here).
(define_insn_reservation "r24k_int_unknown" 0
(and (eq_attr "cpu" "24kc,24kf2_1,24kf1_1")
- (eq_attr "type" "unknown"))
+ (eq_attr "type" "unknown,atomic,syncloop"))
"r24k_iss")
diff --git a/gcc/config/mips/4130.md b/gcc/config/mips/4130.md
index da9ff7e..fd1001f 100644
--- a/gcc/config/mips/4130.md
+++ b/gcc/config/mips/4130.md
@@ -78,7 +78,7 @@
(define_insn_reservation "vr4130_multi" 1
(and (eq_attr "cpu" "r4130")
- (eq_attr "type" "multi,unknown"))
+ (eq_attr "type" "multi,unknown,atomic,syncloop"))
"vr4130_alu1 + vr4130_alu2 + vr4130_dcache + vr4130_muldiv")
(define_insn_reservation "vr4130_int" 1
diff --git a/gcc/config/mips/4k.md b/gcc/config/mips/4k.md
index 2494c63..3733047 100644
--- a/gcc/config/mips/4k.md
+++ b/gcc/config/mips/4k.md
@@ -149,5 +149,5 @@
;; Unknown or multi - single issue
(define_insn_reservation "r4k_unknown" 1
(and (eq_attr "cpu" "4kc,4kp")
- (eq_attr "type" "unknown,multi"))
+ (eq_attr "type" "unknown,multi,atomic,syncloop"))
"r4k_ixu_arith+r4k_ixu_mpydiv")
diff --git a/gcc/config/mips/5400.md b/gcc/config/mips/5400.md
index 40e7e36..f85a311 100644
--- a/gcc/config/mips/5400.md
+++ b/gcc/config/mips/5400.md
@@ -33,7 +33,7 @@
(define_insn_reservation "ir_vr54_unknown" 1
(and (eq_attr "cpu" "r5400")
- (eq_attr "type" "unknown"))
+ (eq_attr "type" "unknown,atomic,syncloop"))
"vr54_dp0+vr54_dp1+vr54_mem+vr54_mac")
;; Assume prediction fails.
diff --git a/gcc/config/mips/5500.md b/gcc/config/mips/5500.md
index 6467fad..b254a9b 100644
--- a/gcc/config/mips/5500.md
+++ b/gcc/config/mips/5500.md
@@ -35,7 +35,7 @@
(define_insn_reservation "ir_vr55_unknown" 1
(and (eq_attr "cpu" "r5500")
- (eq_attr "type" "unknown"))
+ (eq_attr "type" "unknown,atomic,syncloop"))
"vr55_dp0+vr55_dp1+vr55_mem+vr55_mac+vr55_fp+vr55_bru")
;; Assume prediction fails.
diff --git a/gcc/config/mips/5k.md b/gcc/config/mips/5k.md
index 956d0e4..7a0689b 100644
--- a/gcc/config/mips/5k.md
+++ b/gcc/config/mips/5k.md
@@ -127,7 +127,7 @@
;; Unknown or multi - single issue
(define_insn_reservation "r5k_int_unknown" 1
(and (eq_attr "cpu" "5kc,5kf")
- (eq_attr "type" "unknown,multi"))
+ (eq_attr "type" "unknown,multi,atomic,syncloop"))
"r5k_ixu_arith+r5k_ixu_mpydiv")
diff --git a/gcc/config/mips/7000.md b/gcc/config/mips/7000.md
index b348f93..d7265f4 100644
--- a/gcc/config/mips/7000.md
+++ b/gcc/config/mips/7000.md
@@ -210,5 +210,5 @@
;; Force single-dispatch for unknown or multi.
(define_insn_reservation "rm7_unknown" 1
(and (eq_attr "cpu" "r7000")
- (eq_attr "type" "unknown,multi"))
+ (eq_attr "type" "unknown,multi,atomic,syncloop"))
"rm7_single_dispatch")
diff --git a/gcc/config/mips/74k.md b/gcc/config/mips/74k.md
index b643b65..cd0a76d 100644
--- a/gcc/config/mips/74k.md
+++ b/gcc/config/mips/74k.md
@@ -129,7 +129,7 @@
;;
(define_insn_reservation "r74k_unknown" 1
(and (eq_attr "cpu" "74kc,74kf2_1,74kf1_1,74kf3_2")
- (eq_attr "type" "unknown"))
+ (eq_attr "type" "unknown,atomic,syncloop"))
"r74k_alu")
(define_insn_reservation "r74k_multi" 10
diff --git a/gcc/config/mips/9000.md b/gcc/config/mips/9000.md
index 6712aeb..09f55b4 100644
--- a/gcc/config/mips/9000.md
+++ b/gcc/config/mips/9000.md
@@ -147,5 +147,5 @@
(define_insn_reservation "rm9k_unknown" 1
(and (eq_attr "cpu" "r9000")
- (eq_attr "type" "unknown,multi"))
+ (eq_attr "type" "unknown,multi,atomic,syncloop"))
"rm9k_m + rm9k_f_int + rm9k_any1 + rm9k_any2")
diff --git a/gcc/config/mips/generic.md b/gcc/config/mips/generic.md
index ffbe4eb..c197ecf 100644
--- a/gcc/config/mips/generic.md
+++ b/gcc/config/mips/generic.md
@@ -103,3 +103,19 @@
(define_insn_reservation "generic_frecip_fsqrt_step" 5
(eq_attr "type" "frdiv1,frdiv2,frsqrt1,frsqrt2")
"alu")
+
+(define_insn_reservation "generic_atomic" 10
+ (eq_attr "type" "atomic")
+ "alu")
+
+;; Sync loop consists of (in order)
+;; (1) optional sync,
+;; (2) LL instruction,
+;; (3) branch and 1-2 ALU instructions,
+;; (4) SC instruction,
+;; (5) branch and ALU instruction.
+;; The net result of this reservation is a big delay with a flush of
+;; ALU pipeline.
+(define_insn_reservation "generic_sync_loop" 40
+ (eq_attr "type" "syncloop")
+ "alu*39")
diff --git a/gcc/config/mips/loongson2ef.md b/gcc/config/mips/loongson2ef.md
index 5b635c9..ef9dd38 100644
--- a/gcc/config/mips/loongson2ef.md
+++ b/gcc/config/mips/loongson2ef.md
@@ -98,7 +98,7 @@
;; ls2_[f]alu{1,2}_turn_enabled units according to this attribute.
;; These instructions are used in mips.c: sched_ls2_dfa_post_advance_cycle.
-(define_attr "ls2_turn_type" "alu1,alu2,falu1,falu2,unknown"
+(define_attr "ls2_turn_type" "alu1,alu2,falu1,falu2,unknown,atomic,syncloop"
(const_string "unknown"))
;; Subscribe ls2_alu1_turn_enabled.
diff --git a/gcc/config/mips/loongson3a.md b/gcc/config/mips/loongson3a.md
index deaf10e..f1f8762 100644
--- a/gcc/config/mips/loongson3a.md
+++ b/gcc/config/mips/loongson3a.md
@@ -131,7 +131,7 @@
;; Force single-dispatch for unknown or multi.
(define_insn_reservation "ls3a_unknown" 1
(and (eq_attr "cpu" "loongson_3a")
- (eq_attr "type" "unknown,multi"))
+ (eq_attr "type" "unknown,multi,atomic,syncloop"))
"ls3a_alu1 + ls3a_alu2 + ls3a_falu1 + ls3a_falu2 + ls3a_mem")
;; End of DFA-based pipeline description for loongson_3a
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 77bc009..b6b2beb 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -224,6 +224,57 @@
(const_string "yes")]
(const_string "no")))
+;; Attributes describing a sync loop. These loops have the form:
+;;
+;; if (RELEASE_BARRIER == YES) sync
+;; 1: OLDVAL = *MEM
+;; if ((OLDVAL & INCLUSIVE_MASK) != REQUIRED_OLDVAL) goto 2
+;; CMP = 0 [delay slot]
+;; $TMP1 = OLDVAL & EXCLUSIVE_MASK
+;; $TMP2 = INSN1 (OLDVAL, INSN1_OP2)
+;; $TMP3 = INSN2 ($TMP2, INCLUSIVE_MASK)
+;; $AT |= $TMP1 | $TMP3
+;; if (!commit (*MEM = $AT)) goto 1.
+;; if (INSN1 != MOVE && INSN1 != LI) NEWVAL = $TMP3 [delay slot]
+;; CMP = 1
+;; if (ACQUIRE_BARRIER == YES) sync
+;; 2:
+;;
+;; where "$" values are temporaries and where the other values are
+;; specified by the attributes below. Values are specified as operand
+;; numbers and insns are specified as enums. If no operand number is
+;; specified, the following values are used instead:
+;;
+;; - OLDVAL: $AT
+;; - CMP: NONE
+;; - NEWVAL: $AT
+;; - INCLUSIVE_MASK: -1
+;; - REQUIRED_OLDVAL: OLDVAL & INCLUSIVE_MASK
+;; - EXCLUSIVE_MASK: 0
+;;
+;; MEM and INSN1_OP2 are required.
+;;
+;; Ideally, the operand attributes would be integers, with -1 meaning "none",
+;; but the gen* programs don't yet support that.
+(define_attr "sync_mem" "none,0,1,2,3,4,5" (const_string "none"))
+(define_attr "sync_oldval" "none,0,1,2,3,4,5" (const_string "none"))
+(define_attr "sync_cmp" "none,0,1,2,3,4,5" (const_string "none"))
+(define_attr "sync_newval" "none,0,1,2,3,4,5" (const_string "none"))
+(define_attr "sync_inclusive_mask" "none,0,1,2,3,4,5" (const_string "none"))
+(define_attr "sync_exclusive_mask" "none,0,1,2,3,4,5" (const_string "none"))
+(define_attr "sync_required_oldval" "none,0,1,2,3,4,5" (const_string "none"))
+(define_attr "sync_insn1_op2" "none,0,1,2,3,4,5" (const_string "none"))
+(define_attr "sync_insn1" "move,li,addu,addiu,subu,and,andi,or,ori,xor,xori"
+ (const_string "move"))
+(define_attr "sync_insn2" "nop,and,xor,not"
+ (const_string "nop"))
+;; Memory model specifier.
+;; "0"-"9" values specify the operand that stores the memory model value.
+;; "10" specifies MEMMODEL_ACQ_REL,
+;; "11" specifies MEMMODEL_ACQUIRE.
+(define_attr "sync_memmodel" "" (const_int 10))
+
+
;; Classification of each insn.
;; branch conditional branch
;; jump unconditional jump
@@ -276,6 +327,8 @@
;; frsqrt1 floating point reciprocal square root step1
;; frsqrt2 floating point reciprocal square root step2
;; multi multiword sequence (or user asm statements)
+;; atomic atomic memory update instruction
+;; syncloop memory atomic operation implemented as a sync loop
;; nop no operation
;; ghost an instruction that produces no real code
(define_attr "type"
@@ -283,7 +336,7 @@
prefetch,prefetchx,condmove,mtc,mfc,mthi,mtlo,mfhi,mflo,const,arith,logical,
shift,slt,signext,clz,pop,trap,imul,imul3,imul3nc,imadd,idiv,idiv3,move,
fmove,fadd,fmul,fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt,
- frsqrt,frsqrt1,frsqrt2,multi,nop,ghost"
+ frsqrt,frsqrt1,frsqrt2,multi,atomic,syncloop,nop,ghost"
(cond [(eq_attr "jal" "!unset") (const_string "call")
(eq_attr "got" "load") (const_string "load")
@@ -322,7 +375,8 @@
(eq_attr "dword_mode" "yes"))
(const_string "multi")
(eq_attr "move_type" "move") (const_string "move")
- (eq_attr "move_type" "const") (const_string "const")]
+ (eq_attr "move_type" "const") (const_string "const")
+ (eq_attr "sync_mem" "!none") (const_string "syncloop")]
;; We classify "lui_movf" as "unknown" rather than "multi"
;; because we don't split it. FIXME: we should split instead.
(const_string "unknown")))
@@ -346,56 +400,6 @@
(const_string "yes")
(const_string "no")))
-;; Attributes describing a sync loop. These loops have the form:
-;;
-;; if (RELEASE_BARRIER == YES) sync
-;; 1: OLDVAL = *MEM
-;; if ((OLDVAL & INCLUSIVE_MASK) != REQUIRED_OLDVAL) goto 2
-;; CMP = 0 [delay slot]
-;; $TMP1 = OLDVAL & EXCLUSIVE_MASK
-;; $TMP2 = INSN1 (OLDVAL, INSN1_OP2)
-;; $TMP3 = INSN2 ($TMP2, INCLUSIVE_MASK)
-;; $AT |= $TMP1 | $TMP3
-;; if (!commit (*MEM = $AT)) goto 1.
-;; if (INSN1 != MOVE && INSN1 != LI) NEWVAL = $TMP3 [delay slot]
-;; CMP = 1
-;; if (ACQUIRE_BARRIER == YES) sync
-;; 2:
-;;
-;; where "$" values are temporaries and where the other values are
-;; specified by the attributes below. Values are specified as operand
-;; numbers and insns are specified as enums. If no operand number is
-;; specified, the following values are used instead:
-;;
-;; - OLDVAL: $AT
-;; - CMP: NONE
-;; - NEWVAL: $AT
-;; - INCLUSIVE_MASK: -1
-;; - REQUIRED_OLDVAL: OLDVAL & INCLUSIVE_MASK
-;; - EXCLUSIVE_MASK: 0
-;;
-;; MEM and INSN1_OP2 are required.
-;;
-;; Ideally, the operand attributes would be integers, with -1 meaning "none",
-;; but the gen* programs don't yet support that.
-(define_attr "sync_mem" "none,0,1,2,3,4,5" (const_string "none"))
-(define_attr "sync_oldval" "none,0,1,2,3,4,5" (const_string "none"))
-(define_attr "sync_cmp" "none,0,1,2,3,4,5" (const_string "none"))
-(define_attr "sync_newval" "none,0,1,2,3,4,5" (const_string "none"))
-(define_attr "sync_inclusive_mask" "none,0,1,2,3,4,5" (const_string "none"))
-(define_attr "sync_exclusive_mask" "none,0,1,2,3,4,5" (const_string "none"))
-(define_attr "sync_required_oldval" "none,0,1,2,3,4,5" (const_string "none"))
-(define_attr "sync_insn1_op2" "none,0,1,2,3,4,5" (const_string "none"))
-(define_attr "sync_insn1" "move,li,addu,addiu,subu,and,andi,or,ori,xor,xori"
- (const_string "move"))
-(define_attr "sync_insn2" "nop,and,xor,not"
- (const_string "nop"))
-;; Memory model specifier.
-;; "0"-"9" values specify the operand that stores the memory model value.
-;; "10" specifies MEMMODEL_ACQ_REL,
-;; "11" specifies MEMMODEL_ACQUIRE.
-(define_attr "sync_memmodel" "" (const_int 10))
-
;; Length of instruction in bytes.
(define_attr "length" ""
(cond [(and (eq_attr "extended_mips16" "yes")
diff --git a/gcc/config/mips/octeon.md b/gcc/config/mips/octeon.md
index ff6b657..2a57881 100644
--- a/gcc/config/mips/octeon.md
+++ b/gcc/config/mips/octeon.md
@@ -133,5 +133,5 @@
(define_insn_reservation "octeon_unknown" 1
(and (eq_attr "cpu" "octeon,octeon2")
- (eq_attr "type" "unknown,multi"))
+ (eq_attr "type" "unknown,multi,atomic,syncloop"))
"octeon_pipe0 + octeon_pipe1")
diff --git a/gcc/config/mips/sb1.md b/gcc/config/mips/sb1.md
index f0df6f9..f4c4f03 100644
--- a/gcc/config/mips/sb1.md
+++ b/gcc/config/mips/sb1.md
@@ -108,7 +108,7 @@
(define_insn_reservation "ir_sb1_unknown" 1
(and (eq_attr "cpu" "sb1,sb1a")
- (eq_attr "type" "unknown,multi"))
+ (eq_attr "type" "unknown,multi,atomic,syncloop"))
"sb1_ls0+sb1_ls1+sb1_ex0+sb1_ex1+sb1_fp0+sb1_fp1")
;; predicted taken branch causes 2 cycle ifetch bubble. predicted not
diff --git a/gcc/config/mips/sr71k.md b/gcc/config/mips/sr71k.md
index fb0c853..58013ca 100644
--- a/gcc/config/mips/sr71k.md
+++ b/gcc/config/mips/sr71k.md
@@ -144,7 +144,7 @@
(define_insn_reservation "ir_sr70_unknown" 1
(and (eq_attr "cpu" "sr71000")
- (eq_attr "type" "unknown"))
+ (eq_attr "type" "unknown,atomic,syncloop"))
"serial_dispatch")
diff --git a/gcc/config/mips/sync.md b/gcc/config/mips/sync.md
index 0a7905a..4c8dde9 100644
--- a/gcc/config/mips/sync.md
+++ b/gcc/config/mips/sync.md
@@ -654,7 +654,8 @@
(unspec_volatile:GPR [(match_operand:GPR 2 "register_operand" "0")]
UNSPEC_ATOMIC_EXCHANGE))]
"ISA_HAS_SWAP"
- "swap<size>\t%0,%b1")
+ "swap<size>\t%0,%b1"
+ [(set_attr "type" "atomic")])
(define_expand "atomic_fetch_add<mode>"
[(match_operand:GPR 0 "register_operand")
@@ -712,4 +713,5 @@
(match_operand:GPR 2 "register_operand" "0"))]
UNSPEC_ATOMIC_FETCH_OP))]
"ISA_HAS_LDADD"
- "ldadd<size>\t%0,%b1")
+ "ldadd<size>\t%0,%b1"
+ [(set_attr "type" "atomic")])
diff --git a/gcc/config/mips/xlr.md b/gcc/config/mips/xlr.md
index e433d85..1420469 100644
--- a/gcc/config/mips/xlr.md
+++ b/gcc/config/mips/xlr.md
@@ -31,7 +31,7 @@
;; Integer arithmetic instructions.
(define_insn_reservation "ir_xlr_alu" 1
(and (eq_attr "cpu" "xlr")
- (eq_attr "type" "move,arith,shift,clz,logical,signext,const,unknown,multi,nop,trap"))
+ (eq_attr "type" "move,arith,shift,clz,logical,signext,const,unknown,multi,nop,trap,atomic,syncloop"))
"xlr_main_pipe")
;; Integer arithmetic instructions.