xref: /llvm-project/llvm/test/CodeGen/Mips/dins.ll (revision d8a5fae6913a0f6c7e3c814315c1a11fcfd609a1)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
2; RUN: llc -O2 -verify-machineinstrs -mtriple=mips64-elf -mcpu=mips64r2 \
3; RUN:   -target-abi=n64 < %s -o - | FileCheck %s -check-prefix=MIPS64R2
4; RUN: llc -O2 -verify-machineinstrs -mtriple=mips-elf -mcpu=mips32r2 < %s -o - \
5; RUN:   | FileCheck %s -check-prefix=MIPS32R2
6; RUN: llc -O2 -verify-machineinstrs -mtriple=mips-elf -mattr=mips16 < %s -o - \
7; RUN:   | FileCheck %s -check-prefix=MIPS16
8; RUN: llc -O2 -verify-machineinstrs -mtriple=mips64-elf -mcpu=mips64r2 \
9; RUN:   -target-abi=n32 < %s -o - | FileCheck %s -check-prefix=MIPS64R2N32
10
11; #include <stdint.h>
12; #include <stdio.h>
13; struct cvmx_buf_ptr {
14
15;   struct {
16;     unsigned long long addr :37;
17;     unsigned long long addr1 :15;
18;     unsigned int length:14;
19;     uint64_t total_bytes:16;
20;     uint64_t segs : 6;
21;   } s;
22; }
23;
24; unsigned long long foo(volatile struct cvmx_buf_ptr bufptr) {
25;   bufptr.s.addr = 123;
26;   bufptr.s.segs = 4;
27;   bufptr.s.length = 5;
28;   bufptr.s.total_bytes = bufptr.s.length;
29;   return bufptr.s.addr;
30; }
31
32; Testing of selection INS/DINS instruction
33
34define i64 @f123(i64 inreg %bufptr.coerce0, i64 inreg %bufptr.coerce1) local_unnamed_addr #0 {
35; MIPS64R2-LABEL: f123:
36; MIPS64R2:       # %bb.0: # %entry
37; MIPS64R2-NEXT:    daddiu $sp, $sp, -16
38; MIPS64R2-NEXT:    .cfi_def_cfa_offset 16
39; MIPS64R2-NEXT:    sd $4, 8($sp)
40; MIPS64R2-NEXT:    sd $5, 0($sp)
41; MIPS64R2-NEXT:    daddiu $1, $zero, 123
42; MIPS64R2-NEXT:    ld $2, 8($sp)
43; MIPS64R2-NEXT:    dinsm $2, $1, 27, 37
44; MIPS64R2-NEXT:    sd $2, 8($sp)
45; MIPS64R2-NEXT:    daddiu $1, $zero, 4
46; MIPS64R2-NEXT:    ld $2, 0($sp)
47; MIPS64R2-NEXT:    dinsm $2, $1, 28, 6
48; MIPS64R2-NEXT:    daddiu $1, $zero, 5
49; MIPS64R2-NEXT:    sd $2, 0($sp)
50; MIPS64R2-NEXT:    ld $2, 0($sp)
51; MIPS64R2-NEXT:    dinsu $2, $1, 50, 14
52; MIPS64R2-NEXT:    sd $2, 0($sp)
53; MIPS64R2-NEXT:    ld $1, 0($sp)
54; MIPS64R2-NEXT:    dsrl $1, $1, 50
55; MIPS64R2-NEXT:    ld $2, 0($sp)
56; MIPS64R2-NEXT:    dinsu $2, $1, 34, 16
57; MIPS64R2-NEXT:    sd $2, 0($sp)
58; MIPS64R2-NEXT:    ld $1, 8($sp)
59; MIPS64R2-NEXT:    dsrl $2, $1, 27
60; MIPS64R2-NEXT:    jr $ra
61; MIPS64R2-NEXT:    daddiu $sp, $sp, 16
62;
63; MIPS32R2-LABEL: f123:
64; MIPS32R2:       # %bb.0: # %entry
65; MIPS32R2-NEXT:    addiu $sp, $sp, -16
66; MIPS32R2-NEXT:    .cfi_def_cfa_offset 16
67; MIPS32R2-NEXT:    lw $1, 8($sp)
68; MIPS32R2-NEXT:    lw $1, 12($sp)
69; MIPS32R2-NEXT:    addiu $2, $zero, 3
70; MIPS32R2-NEXT:    sw $2, 8($sp)
71; MIPS32R2-NEXT:    ext $1, $1, 0, 27
72; MIPS32R2-NEXT:    lui $2, 55296
73; MIPS32R2-NEXT:    or $1, $1, $2
74; MIPS32R2-NEXT:    sw $1, 12($sp)
75; MIPS32R2-NEXT:    addiu $1, $zero, -4
76; MIPS32R2-NEXT:    lw $2, 0($sp)
77; MIPS32R2-NEXT:    and $1, $2, $1
78; MIPS32R2-NEXT:    lw $2, 4($sp)
79; MIPS32R2-NEXT:    sw $1, 0($sp)
80; MIPS32R2-NEXT:    ext $1, $2, 0, 28
81; MIPS32R2-NEXT:    lui $2, 16384
82; MIPS32R2-NEXT:    or $1, $1, $2
83; MIPS32R2-NEXT:    lui $2, 20
84; MIPS32R2-NEXT:    sw $1, 4($sp)
85; MIPS32R2-NEXT:    lw $1, 0($sp)
86; MIPS32R2-NEXT:    lw $3, 4($sp)
87; MIPS32R2-NEXT:    sw $3, 4($sp)
88; MIPS32R2-NEXT:    ext $1, $1, 0, 18
89; MIPS32R2-NEXT:    or $1, $1, $2
90; MIPS32R2-NEXT:    sw $1, 0($sp)
91; MIPS32R2-NEXT:    lw $1, 4($sp)
92; MIPS32R2-NEXT:    lw $1, 0($sp)
93; MIPS32R2-NEXT:    lw $2, 0($sp)
94; MIPS32R2-NEXT:    lw $3, 4($sp)
95; MIPS32R2-NEXT:    sw $3, 4($sp)
96; MIPS32R2-NEXT:    srl $1, $1, 18
97; MIPS32R2-NEXT:    ins $2, $1, 2, 16
98; MIPS32R2-NEXT:    sw $2, 0($sp)
99; MIPS32R2-NEXT:    lw $1, 8($sp)
100; MIPS32R2-NEXT:    sll $2, $1, 5
101; MIPS32R2-NEXT:    lw $3, 12($sp)
102; MIPS32R2-NEXT:    srl $3, $3, 27
103; MIPS32R2-NEXT:    or $3, $3, $2
104; MIPS32R2-NEXT:    srl $2, $1, 27
105; MIPS32R2-NEXT:    jr $ra
106; MIPS32R2-NEXT:    addiu $sp, $sp, 16
107;
108; MIPS16-LABEL: f123:
109; MIPS16:       # %bb.0: # %entry
110; MIPS16-NEXT:    save 16 # 16 bit inst
111; MIPS16-EMPTY:
112; MIPS16-NEXT:    .cfi_def_cfa_offset 16
113; MIPS16-NEXT:    lw $2, 8($sp)
114; MIPS16-NEXT:    lw $2, 12($sp)
115; MIPS16-NEXT:    li $3, 3
116; MIPS16-NEXT:    sw $3, 8($sp)
117; MIPS16-NEXT:    lw $3, $CPI0_0 # 16 bit inst
118; MIPS16-NEXT:    and $3, $2
119; MIPS16-NEXT:    lw $2, $CPI0_1 # 16 bit inst
120; MIPS16-NEXT:    or $2, $3
121; MIPS16-NEXT:    sw $2, 12($sp)
122; MIPS16-NEXT:    move $2, $zero
123; MIPS16-NEXT:    addiu $2, -4
124; MIPS16-NEXT:    lw $3, 0($sp)
125; MIPS16-NEXT:    and $3, $2
126; MIPS16-NEXT:    lw $2, 4($sp)
127; MIPS16-NEXT:    sw $3, 0($sp)
128; MIPS16-NEXT:    lw $3, $CPI0_2 # 16 bit inst
129; MIPS16-NEXT:    and $3, $2
130; MIPS16-NEXT:    lw $2, $CPI0_3 # 16 bit inst
131; MIPS16-NEXT:    or $2, $3
132; MIPS16-NEXT:    sw $2, 4($sp)
133; MIPS16-NEXT:    lw $2, 0($sp)
134; MIPS16-NEXT:    lw $3, 4($sp)
135; MIPS16-NEXT:    sw $3, 4($sp)
136; MIPS16-NEXT:    lw $3, $CPI0_4 # 16 bit inst
137; MIPS16-NEXT:    and $3, $2
138; MIPS16-NEXT:    lw $2, $CPI0_5 # 16 bit inst
139; MIPS16-NEXT:    or $2, $3
140; MIPS16-NEXT:    sw $2, 0($sp)
141; MIPS16-NEXT:    lw $2, 4($sp)
142; MIPS16-NEXT:    lw $2, 0($sp)
143; MIPS16-NEXT:    lw $3, 0($sp)
144; MIPS16-NEXT:    lw $4, 4($sp)
145; MIPS16-NEXT:    sw $4, 4($sp)
146; MIPS16-NEXT:    srl $2, $2, 16
147; MIPS16-NEXT:    li $4, 65532
148; MIPS16-NEXT:    and $4, $2
149; MIPS16-NEXT:    lw $2, $CPI0_6 # 16 bit inst
150; MIPS16-NEXT:    and $2, $3
151; MIPS16-NEXT:    or $2, $4
152; MIPS16-NEXT:    sw $2, 0($sp)
153; MIPS16-NEXT:    lw $2, 12($sp)
154; MIPS16-NEXT:    srl $2, $2, 27
155; MIPS16-NEXT:    lw $4, 8($sp)
156; MIPS16-NEXT:    sll $3, $4, 5
157; MIPS16-NEXT:    or $3, $2
158; MIPS16-NEXT:    srl $2, $4, 27
159; MIPS16-NEXT:    restore 16 # 16 bit inst
160; MIPS16-EMPTY:
161; MIPS16-NEXT:    jrc $ra
162; MIPS16-NEXT:    .p2align 2
163; MIPS16-NEXT:  # %bb.1:
164; MIPS16-NEXT:  $CPI0_0:
165; MIPS16-NEXT:    .4byte 134217727 # 0x7ffffff
166; MIPS16-NEXT:  $CPI0_1:
167; MIPS16-NEXT:    .4byte 3623878656 # 0xd8000000
168; MIPS16-NEXT:  $CPI0_2:
169; MIPS16-NEXT:    .4byte 268435455 # 0xfffffff
170; MIPS16-NEXT:  $CPI0_3:
171; MIPS16-NEXT:    .4byte 1073741824 # 0x40000000
172; MIPS16-NEXT:  $CPI0_4:
173; MIPS16-NEXT:    .4byte 262143 # 0x3ffff
174; MIPS16-NEXT:  $CPI0_5:
175; MIPS16-NEXT:    .4byte 1310720 # 0x140000
176; MIPS16-NEXT:  $CPI0_6:
177; MIPS16-NEXT:    .4byte 4294705155 # 0xfffc0003
178;
179; MIPS64R2N32-LABEL: f123:
180; MIPS64R2N32:       # %bb.0: # %entry
181; MIPS64R2N32-NEXT:    addiu $sp, $sp, -16
182; MIPS64R2N32-NEXT:    .cfi_def_cfa_offset 16
183; MIPS64R2N32-NEXT:    sd $4, 8($sp)
184; MIPS64R2N32-NEXT:    sd $5, 0($sp)
185; MIPS64R2N32-NEXT:    daddiu $1, $zero, 123
186; MIPS64R2N32-NEXT:    ld $2, 8($sp)
187; MIPS64R2N32-NEXT:    dinsm $2, $1, 27, 37
188; MIPS64R2N32-NEXT:    sd $2, 8($sp)
189; MIPS64R2N32-NEXT:    daddiu $1, $zero, 4
190; MIPS64R2N32-NEXT:    ld $2, 0($sp)
191; MIPS64R2N32-NEXT:    dinsm $2, $1, 28, 6
192; MIPS64R2N32-NEXT:    daddiu $1, $zero, 5
193; MIPS64R2N32-NEXT:    sd $2, 0($sp)
194; MIPS64R2N32-NEXT:    ld $2, 0($sp)
195; MIPS64R2N32-NEXT:    dinsu $2, $1, 50, 14
196; MIPS64R2N32-NEXT:    sd $2, 0($sp)
197; MIPS64R2N32-NEXT:    ld $1, 0($sp)
198; MIPS64R2N32-NEXT:    dsrl $1, $1, 50
199; MIPS64R2N32-NEXT:    ld $2, 0($sp)
200; MIPS64R2N32-NEXT:    dinsu $2, $1, 34, 16
201; MIPS64R2N32-NEXT:    sd $2, 0($sp)
202; MIPS64R2N32-NEXT:    ld $1, 8($sp)
203; MIPS64R2N32-NEXT:    dsrl $2, $1, 27
204; MIPS64R2N32-NEXT:    jr $ra
205; MIPS64R2N32-NEXT:    addiu $sp, $sp, 16
206entry:
207  %bufptr.sroa.0 = alloca i64, align 8
208  %bufptr.sroa.4 = alloca i64, align 8
209  store i64 %bufptr.coerce0, ptr %bufptr.sroa.0, align 8
210  store i64 %bufptr.coerce1, ptr %bufptr.sroa.4, align 8
211  %bufptr.sroa.0.0.bufptr.sroa.0.0.bufptr.sroa.0.0.bf.load = load volatile i64, ptr %bufptr.sroa.0, align 8
212  %bf.clear = and i64 %bufptr.sroa.0.0.bufptr.sroa.0.0.bufptr.sroa.0.0.bf.load, 134217727
213  %bf.set = or i64 %bf.clear, 16508780544
214  store volatile i64 %bf.set, ptr %bufptr.sroa.0, align 8
215  %bufptr.sroa.4.0.bufptr.sroa.4.0.bufptr.sroa.4.8.bf.load2 = load volatile i64, ptr %bufptr.sroa.4, align 8
216  %bf.clear3 = and i64 %bufptr.sroa.4.0.bufptr.sroa.4.0.bufptr.sroa.4.8.bf.load2, -16911433729
217  %bf.set4 = or i64 %bf.clear3, 1073741824
218  store volatile i64 %bf.set4, ptr %bufptr.sroa.4, align 8
219  %bufptr.sroa.4.0.bufptr.sroa.4.0.bufptr.sroa.4.8.bf.load6 = load volatile i64, ptr %bufptr.sroa.4, align 8
220  %bf.clear7 = and i64 %bufptr.sroa.4.0.bufptr.sroa.4.0.bufptr.sroa.4.8.bf.load6, 1125899906842623
221  %bf.set8 = or i64 %bf.clear7, 5629499534213120
222  store volatile i64 %bf.set8, ptr %bufptr.sroa.4, align 8
223  %bufptr.sroa.4.0.bufptr.sroa.4.0.bufptr.sroa.4.8.bf.load11 = load volatile i64, ptr %bufptr.sroa.4, align 8
224  %bf.lshr = lshr i64 %bufptr.sroa.4.0.bufptr.sroa.4.0.bufptr.sroa.4.8.bf.load11, 50
225  %bufptr.sroa.4.0.bufptr.sroa.4.0.bufptr.sroa.4.8.bf.load13 = load volatile i64, ptr %bufptr.sroa.4, align 8
226  %bf.shl = shl nuw nsw i64 %bf.lshr, 34
227  %bf.clear14 = and i64 %bufptr.sroa.4.0.bufptr.sroa.4.0.bufptr.sroa.4.8.bf.load13, -1125882726973441
228  %bf.set15 = or i64 %bf.clear14, %bf.shl
229  store volatile i64 %bf.set15, ptr %bufptr.sroa.4, align 8
230  %bufptr.sroa.0.0.bufptr.sroa.0.0.bufptr.sroa.0.0.bf.load17 = load volatile i64, ptr %bufptr.sroa.0, align 8
231  %bf.lshr18 = lshr i64 %bufptr.sroa.0.0.bufptr.sroa.0.0.bufptr.sroa.0.0.bf.load17, 27
232  ret i64 %bf.lshr18
233}
234
235; int foo(volatile int x) {
236;   int y = x;
237;   y = y & -4;
238;   x = y | 8;
239;   return y;
240; }
241
242define i32 @foo(i32 signext %x) {
243; MIPS64R2-LABEL: foo:
244; MIPS64R2:       # %bb.0: # %entry
245; MIPS64R2-NEXT:    daddiu $sp, $sp, -16
246; MIPS64R2-NEXT:    .cfi_def_cfa_offset 16
247; MIPS64R2-NEXT:    sw $4, 12($sp)
248; MIPS64R2-NEXT:    addiu $1, $zero, -4
249; MIPS64R2-NEXT:    lw $2, 12($sp)
250; MIPS64R2-NEXT:    and $2, $2, $1
251; MIPS64R2-NEXT:    ori $1, $2, 8
252; MIPS64R2-NEXT:    sw $1, 12($sp)
253; MIPS64R2-NEXT:    jr $ra
254; MIPS64R2-NEXT:    daddiu $sp, $sp, 16
255;
256; MIPS32R2-LABEL: foo:
257; MIPS32R2:       # %bb.0: # %entry
258; MIPS32R2-NEXT:    addiu $sp, $sp, -8
259; MIPS32R2-NEXT:    .cfi_def_cfa_offset 8
260; MIPS32R2-NEXT:    sw $4, 4($sp)
261; MIPS32R2-NEXT:    addiu $1, $zero, -4
262; MIPS32R2-NEXT:    lw $2, 4($sp)
263; MIPS32R2-NEXT:    and $2, $2, $1
264; MIPS32R2-NEXT:    ori $1, $2, 8
265; MIPS32R2-NEXT:    sw $1, 4($sp)
266; MIPS32R2-NEXT:    jr $ra
267; MIPS32R2-NEXT:    addiu $sp, $sp, 8
268;
269; MIPS16-LABEL: foo:
270; MIPS16:       # %bb.0: # %entry
271; MIPS16-NEXT:    save 8 # 16 bit inst
272; MIPS16-EMPTY:
273; MIPS16-NEXT:    .cfi_def_cfa_offset 8
274; MIPS16-NEXT:    sw $4, 4($sp)
275; MIPS16-NEXT:    move $3, $zero
276; MIPS16-NEXT:    addiu $3, -4
277; MIPS16-NEXT:    lw $2, 4($sp)
278; MIPS16-NEXT:    and $2, $3
279; MIPS16-NEXT:    li $3, 8
280; MIPS16-NEXT:    or $3, $2
281; MIPS16-NEXT:    sw $3, 4($sp)
282; MIPS16-NEXT:    restore 8 # 16 bit inst
283; MIPS16-EMPTY:
284; MIPS16-NEXT:    jrc $ra
285;
286; MIPS64R2N32-LABEL: foo:
287; MIPS64R2N32:       # %bb.0: # %entry
288; MIPS64R2N32-NEXT:    addiu $sp, $sp, -16
289; MIPS64R2N32-NEXT:    .cfi_def_cfa_offset 16
290; MIPS64R2N32-NEXT:    sw $4, 12($sp)
291; MIPS64R2N32-NEXT:    addiu $1, $zero, -4
292; MIPS64R2N32-NEXT:    lw $2, 12($sp)
293; MIPS64R2N32-NEXT:    and $2, $2, $1
294; MIPS64R2N32-NEXT:    ori $1, $2, 8
295; MIPS64R2N32-NEXT:    sw $1, 12($sp)
296; MIPS64R2N32-NEXT:    jr $ra
297; MIPS64R2N32-NEXT:    addiu $sp, $sp, 16
298entry:
299  %x.addr = alloca i32, align 4
300  store volatile i32 %x, ptr %x.addr, align 4
301  %x.addr.0.x.addr.0. = load volatile i32, ptr %x.addr, align 4
302  %and = and i32 %x.addr.0.x.addr.0., -4
303  %or = or i32 %and, 8
304  store volatile i32 %or, ptr %x.addr, align 4
305  ret i32 %and
306}
307