Skip to content

Commit 2f90cac

Browse files
committed
Use soft ties for x64 addition operations
These weakened ties enable operands to be commuted or `lea` instructions to be emitted where copies would otherwise have been necessary.
1 parent 415648e commit 2f90cac

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+8384
-8808
lines changed

crates/codegen/src/target/x64/emit.rs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,13 +209,45 @@ impl MachineEmit for X64Machine {
209209

210210
match instr.instr {
211211
&X64Instr::AddRR(op_size) => {
212+
let dest = defs[0].as_reg().unwrap();
212213
let arg0 = uses[0].as_reg().unwrap();
213214
let arg1 = uses[1].as_reg().unwrap();
214-
emit_alu_r_rm(buffer, RawAluBinOp::Add, op_size, arg0, RegMem::Reg(arg1));
215+
216+
if dest == arg0 {
217+
emit_alu_r_rm(buffer, RawAluBinOp::Add, op_size, arg0, RegMem::Reg(arg1));
218+
} else if dest == arg1 {
219+
emit_alu_r_rm(buffer, RawAluBinOp::Add, op_size, arg1, RegMem::Reg(arg0));
220+
} else {
221+
emit_lea(
222+
buffer,
223+
op_size,
224+
dest,
225+
RawAddrMode::BaseIndexOff {
226+
base: Some(arg0),
227+
index: Some((IndexScale::One, arg1)),
228+
offset: 0,
229+
},
230+
);
231+
}
215232
}
216233
&X64Instr::AddRI(op_size, imm) => {
234+
let dest = defs[0].as_reg().unwrap();
217235
let arg = uses[0].as_reg().unwrap();
218-
emit_alu_rm_i(buffer, RawAluBinOp::Add, op_size, RegMem::Reg(arg), imm);
236+
237+
if dest == arg {
238+
emit_alu_rm_i(buffer, RawAluBinOp::Add, op_size, RegMem::Reg(arg), imm);
239+
} else {
240+
emit_lea(
241+
buffer,
242+
op_size,
243+
dest,
244+
RawAddrMode::BaseIndexOff {
245+
base: Some(arg),
246+
index: None,
247+
offset: imm,
248+
},
249+
);
250+
}
219251
}
220252
&X64Instr::AluRRm(op_size, op) => {
221253
let arg0 = uses[0].as_reg().unwrap();

crates/codegen/src/target/x64/lower.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -353,14 +353,14 @@ fn select_add(ctx: &mut IselContext<'_, '_, X64Machine>, node: Node) {
353353
ctx.emit_instr(
354354
X64Instr::AddRI(op_size, imm),
355355
&[DefOperand::any_reg(output)],
356-
&[UseOperand::tied(op1, 0)],
356+
&[UseOperand::soft_tied(op1, 0)],
357357
);
358358
} else {
359359
let op2 = ctx.get_value_vreg(op2);
360360
ctx.emit_instr(
361361
X64Instr::AddRR(op_size),
362362
&[DefOperand::any_reg(output)],
363-
&[UseOperand::tied(op1, 0), UseOperand::any_reg(op2)],
363+
&[UseOperand::soft_tied(op1, 0), UseOperand::soft_tied(op2, 0)],
364364
);
365365
}
366366
}

crates/filetests/cases/codegen/add.spdr

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@ func @add64:i64(i64, i64) {
44
# check: function `add64`:
55
# nextln: 000000: 55 push rbp
66
# nextln: 000001: 48 89 e5 mov rbp, rsp
7-
# nextln: 000004: 48 89 f8 mov rax, rdi
8-
# nextln: 000007: 48 03 c6 add rax, rsi
9-
# nextln: 00000a: 5d pop rbp
10-
# nextln: 00000b: c3 ret
7+
# nextln: 000004: 48 8d 04 37 lea rax, [rdi + rsi]
8+
# nextln: 000008: 5d pop rbp
9+
# nextln: 000009: c3 ret
1110

1211
%c:ctrl, %a:i64, %b:i64 = entry
1312
%val:i64 = iadd %a, %b
@@ -18,10 +17,9 @@ func @add32:i32(i32, i32) {
1817
# check: function `add32`:
1918
# nextln: 000000: 55 push rbp
2019
# nextln: 000001: 48 89 e5 mov rbp, rsp
21-
# nextln: 000004: 48 89 f8 mov rax, rdi
22-
# nextln: 000007: 03 c6 add eax, esi
23-
# nextln: 000009: 5d pop rbp
24-
# nextln: 00000a: c3 ret
20+
# nextln: 000004: 8d 04 37 lea eax, [rdi + rsi]
21+
# nextln: 000007: 5d pop rbp
22+
# nextln: 000008: c3 ret
2523

2624
%c:ctrl, %a:i32, %b:i32 = entry
2725
%val:i32 = iadd %a, %b

crates/filetests/cases/codegen/add_const.spdr

Lines changed: 23 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@ func @add_pos64:i64(i64) {
44
# check: function `add_pos64`:
55
# nextln: 000000: 55 push rbp
66
# nextln: 000001: 48 89 e5 mov rbp, rsp
7-
# nextln: 000004: 48 89 f8 mov rax, rdi
8-
# nextln: 000007: 48 83 c0 05 add rax, 5
9-
# nextln: 00000b: 5d pop rbp
10-
# nextln: 00000c: c3 ret
7+
# nextln: 000004: 48 8d 47 05 lea rax, [rdi + 5]
8+
# nextln: 000008: 5d pop rbp
9+
# nextln: 000009: c3 ret
1110

1211
%c:ctrl, %a:i64 = entry
1312
%b:i64 = iconst 5
@@ -19,10 +18,9 @@ func @add_neg64:i64(i64) {
1918
# check: function `add_neg64`:
2019
# nextln: 000000: 55 push rbp
2120
# nextln: 000001: 48 89 e5 mov rbp, rsp
22-
# nextln: 000004: 48 89 f8 mov rax, rdi
23-
# nextln: 000007: 48 83 c0 fb add rax, -5
24-
# nextln: 00000b: 5d pop rbp
25-
# nextln: 00000c: c3 ret
21+
# nextln: 000004: 48 8d 47 fb lea rax, [rdi - 5]
22+
# nextln: 000008: 5d pop rbp
23+
# nextln: 000009: c3 ret
2624

2725
%c:ctrl, %a:i64 = entry
2826
%b:i64 = iconst 18446744073709551611
@@ -34,11 +32,10 @@ func @add_pos_large64:i64(i64) {
3432
# check: function `add_pos_large64`:
3533
# nextln: 000000: 55 push rbp
3634
# nextln: 000001: 48 89 e5 mov rbp, rsp
37-
# nextln: 000004: 48 89 f8 mov rax, rdi
38-
# nextln: 000007: b9 ff ff ff ff mov ecx, 0xffffffff
39-
# nextln: 00000c: 48 03 c1 add rax, rcx
40-
# nextln: 00000f: 5d pop rbp
41-
# nextln: 000010: c3 ret
35+
# nextln: 000004: b8 ff ff ff ff mov eax, 0xffffffff
36+
# nextln: 000009: 48 03 c7 add rax, rdi
37+
# nextln: 00000c: 5d pop rbp
38+
# nextln: 00000d: c3 ret
4239

4340
%c:ctrl, %a:i64 = entry
4441
%b:i64 = iconst 4294967295
@@ -50,11 +47,10 @@ func @add_neg_large64:i64(i64) {
5047
# check: function `add_neg_large64`:
5148
# nextln: 000000: 55 push rbp
5249
# nextln: 000001: 48 89 e5 mov rbp, rsp
53-
# nextln: 000004: 48 89 f8 mov rax, rdi
54-
# nextln: 000007: 48 b9 01 00 00 00 ff ff ff ff movabs rcx, 0xffffffff00000001
55-
# nextln: 000011: 48 03 c1 add rax, rcx
56-
# nextln: 000014: 5d pop rbp
57-
# nextln: 000015: c3 ret
50+
# nextln: 000004: 48 b8 01 00 00 00 ff ff ff ff movabs rax, 0xffffffff00000001
51+
# nextln: 00000e: 48 03 c7 add rax, rdi
52+
# nextln: 000011: 5d pop rbp
53+
# nextln: 000012: c3 ret
5854

5955
%c:ctrl, %a:i64 = entry
6056
%b:i64 = iconst 18446744069414584321
@@ -66,10 +62,9 @@ func @add_pos32:i32(i32) {
6662
# check: function `add_pos32`:
6763
# nextln: 000000: 55 push rbp
6864
# nextln: 000001: 48 89 e5 mov rbp, rsp
69-
# nextln: 000004: 48 89 f8 mov rax, rdi
70-
# nextln: 000007: 83 c0 05 add eax, 5
71-
# nextln: 00000a: 5d pop rbp
72-
# nextln: 00000b: c3 ret
65+
# nextln: 000004: 8d 47 05 lea eax, [rdi + 5]
66+
# nextln: 000007: 5d pop rbp
67+
# nextln: 000008: c3 ret
7368

7469
%c:ctrl, %a:i32 = entry
7570
%b:i32 = iconst 5
@@ -81,10 +76,9 @@ func @add_neg32:i32(i32) {
8176
# check: function `add_neg32`:
8277
# nextln: 000000: 55 push rbp
8378
# nextln: 000001: 48 89 e5 mov rbp, rsp
84-
# nextln: 000004: 48 89 f8 mov rax, rdi
85-
# nextln: 000007: 83 c0 fb add eax, -5
86-
# nextln: 00000a: 5d pop rbp
87-
# nextln: 00000b: c3 ret
79+
# nextln: 000004: 8d 47 fb lea eax, [rdi - 5]
80+
# nextln: 000007: 5d pop rbp
81+
# nextln: 000008: c3 ret
8882

8983
%c:ctrl, %a:i32 = entry
9084
%b:i32 = iconst 4294967291
@@ -96,10 +90,9 @@ func @add_max32:i32(i32) {
9690
# check: function `add_max32`:
9791
# nextln: 000000: 55 push rbp
9892
# nextln: 000001: 48 89 e5 mov rbp, rsp
99-
# nextln: 000004: 48 89 f8 mov rax, rdi
100-
# nextln: 000007: 81 c0 ff ff ff 7f add eax, 0x7fffffff
101-
# nextln: 00000d: 5d pop rbp
102-
# nextln: 00000e: c3 ret
93+
# nextln: 000004: 8d 87 ff ff ff 7f lea eax, [rdi + 0x7fffffff]
94+
# nextln: 00000a: 5d pop rbp
95+
# nextln: 00000b: c3 ret
10396

10497
%c:ctrl, %a:i32 = entry
10598
%b:i32 = iconst 2147483647

crates/filetests/cases/codegen/call_large.spdr

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -67,33 +67,33 @@ func @caller:i32(ptr, i32) {
6767
# nextln: 000006: 41 54 push r12
6868
# nextln: 000008: 53 push rbx
6969
# nextln: 000009: 50 push rax
70-
# nextln: 00000a: 49 89 f5 mov r13, rsi
71-
# nextln: 00000d: 49 89 fc mov r12, rdi
70+
# nextln: 00000a: 49 89 f4 mov r12, rsi
71+
# nextln: 00000d: 48 89 fb mov rbx, rdi
7272
# nextln: 000010: 48 b8 00 00 00 00 00 00 00 00 movabs rax, 0 # RELOC_ABS64 -> @extfunc + 0
7373
# nextln: 00001a: ff d0 call rax
7474
# nextln: 00001c: 48 b8 00 00 00 00 00 00 00 00 movabs rax, 0 # RELOC_ABS64 -> @extfunc2 + 0
75-
# nextln: 000026: 4c 89 ee mov rsi, r13
76-
# nextln: 000029: 4c 89 e7 mov rdi, r12
75+
# nextln: 000026: 4c 89 e6 mov rsi, r12
76+
# nextln: 000029: 48 89 df mov rdi, rbx
7777
# nextln: 00002c: ff d0 call rax
78-
# nextln: 00002e: 48 89 c3 mov rbx, rax
78+
# nextln: 00002e: 49 89 c5 mov r13, rax
7979
# nextln: 000031: 48 b8 00 00 00 00 00 00 00 00 movabs rax, 0 # RELOC_ABS64 -> @infunc + 0
80-
# nextln: 00003b: 4c 89 ee mov rsi, r13
81-
# nextln: 00003e: 4c 89 e7 mov rdi, r12
80+
# nextln: 00003b: 4c 89 e6 mov rsi, r12
81+
# nextln: 00003e: 48 89 df mov rdi, rbx
8282
# nextln: 000041: ff d0 call rax
8383
# nextln: 000043: 48 b8 00 00 00 00 00 00 00 00 movabs rax, 0 # RELOC_ABS64 -> @infunc2 + 0
84-
# nextln: 00004d: 4c 89 ee mov rsi, r13
85-
# nextln: 000050: 4c 89 e7 mov rdi, r12
84+
# nextln: 00004d: 4c 89 e6 mov rsi, r12
85+
# nextln: 000050: 48 89 df mov rdi, rbx
8686
# nextln: 000053: ff d0 call rax
87-
# nextln: 000055: 03 d8 add ebx, eax
88-
# nextln: 000057: 48 b8 00 00 00 00 00 00 00 00 movabs rax, 0 # RELOC_ABS64 -> @no_params + 0
89-
# nextln: 000061: ff d0 call rax
90-
# nextln: 000063: 48 89 d8 mov rax, rbx
91-
# nextln: 000066: 48 83 c4 08 add rsp, 8
92-
# nextln: 00006a: 5b pop rbx
93-
# nextln: 00006b: 41 5c pop r12
94-
# nextln: 00006d: 41 5d pop r13
95-
# nextln: 00006f: 5d pop rbp
96-
# nextln: 000070: c3 ret
87+
# nextln: 000055: 44 03 e8 add r13d, eax
88+
# nextln: 000058: 48 b8 00 00 00 00 00 00 00 00 movabs rax, 0 # RELOC_ABS64 -> @no_params + 0
89+
# nextln: 000062: ff d0 call rax
90+
# nextln: 000064: 4c 89 e8 mov rax, r13
91+
# nextln: 000067: 48 83 c4 08 add rsp, 8
92+
# nextln: 00006b: 5b pop rbx
93+
# nextln: 00006c: 41 5c pop r12
94+
# nextln: 00006e: 41 5d pop r13
95+
# nextln: 000070: 5d pop rbp
96+
# nextln: 000071: c3 ret
9797

9898
%3:ctrl, %1:ptr, %2:i32 = entry
9999
%5:ctrl = call @extfunc %3, %1, %2

crates/filetests/cases/codegen/call_small.spdr

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -67,28 +67,28 @@ func @caller:i32(ptr, i32) {
6767
# nextln: 000006: 41 54 push r12
6868
# nextln: 000008: 53 push rbx
6969
# nextln: 000009: 50 push rax
70-
# nextln: 00000a: 49 89 f5 mov r13, rsi
71-
# nextln: 00000d: 49 89 fc mov r12, rdi
70+
# nextln: 00000a: 49 89 f4 mov r12, rsi
71+
# nextln: 00000d: 48 89 fb mov rbx, rdi
7272
# nextln: 000010: e8 00 00 00 00 call 0x15 # RELOC_PC32 -> @extfunc + -4
73-
# nextln: 000015: 4c 89 ee mov rsi, r13
74-
# nextln: 000018: 4c 89 e7 mov rdi, r12
73+
# nextln: 000015: 4c 89 e6 mov rsi, r12
74+
# nextln: 000018: 48 89 df mov rdi, rbx
7575
# nextln: 00001b: e8 00 00 00 00 call 0x20 # RELOC_PC32 -> @extfunc2 + -4
76-
# nextln: 000020: 48 89 c3 mov rbx, rax
77-
# nextln: 000023: 4c 89 ee mov rsi, r13
78-
# nextln: 000026: 4c 89 e7 mov rdi, r12
76+
# nextln: 000020: 49 89 c5 mov r13, rax
77+
# nextln: 000023: 4c 89 e6 mov rsi, r12
78+
# nextln: 000026: 48 89 df mov rdi, rbx
7979
# nextln: 000029: e8 00 00 00 00 call 0x2e # RELOC_PC32 -> @infunc + -4
80-
# nextln: 00002e: 4c 89 ee mov rsi, r13
81-
# nextln: 000031: 4c 89 e7 mov rdi, r12
80+
# nextln: 00002e: 4c 89 e6 mov rsi, r12
81+
# nextln: 000031: 48 89 df mov rdi, rbx
8282
# nextln: 000034: e8 00 00 00 00 call 0x39 # RELOC_PC32 -> @infunc2 + -4
83-
# nextln: 000039: 03 d8 add ebx, eax
84-
# nextln: 00003b: e8 00 00 00 00 call 0x40 # RELOC_PC32 -> @no_params + -4
85-
# nextln: 000040: 48 89 d8 mov rax, rbx
86-
# nextln: 000043: 48 83 c4 08 add rsp, 8
87-
# nextln: 000047: 5b pop rbx
88-
# nextln: 000048: 41 5c pop r12
89-
# nextln: 00004a: 41 5d pop r13
90-
# nextln: 00004c: 5d pop rbp
91-
# nextln: 00004d: c3 ret
83+
# nextln: 000039: 44 03 e8 add r13d, eax
84+
# nextln: 00003c: e8 00 00 00 00 call 0x41 # RELOC_PC32 -> @no_params + -4
85+
# nextln: 000041: 4c 89 e8 mov rax, r13
86+
# nextln: 000044: 48 83 c4 08 add rsp, 8
87+
# nextln: 000048: 5b pop rbx
88+
# nextln: 000049: 41 5c pop r12
89+
# nextln: 00004b: 41 5d pop r13
90+
# nextln: 00004d: 5d pop rbp
91+
# nextln: 00004e: c3 ret
9292

9393
%3:ctrl, %1:ptr, %2:i32 = entry
9494
%5:ctrl = call @extfunc %3, %1, %2

crates/filetests/cases/codegen/fcmp_brcond.spdr

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -158,17 +158,16 @@ func @select_olt_cond_reused:i32(f64, f64, i32, i32) {
158158
# check: function `select_olt_cond_reused`:
159159
# nextln: 000000: 55 push rbp
160160
# nextln: 000001: 48 89 e5 mov rbp, rsp
161-
# nextln: 000004: 48 89 f8 mov rax, rdi
162-
# nextln: 000007: 33 c9 xor ecx, ecx
163-
# nextln: 000009: 66 0f 2e c8 ucomisd xmm1, xmm0
164-
# nextln: 00000d: 0f 97 c1 seta cl
165-
# nextln: 000010: 85 c9 test ecx, ecx
166-
# nextln: 000012: 0f 85 03 00 00 00 jne 0x1b
167-
# nextln: 000018: 48 89 f0 mov rax, rsi
168-
# nextln: 00001b: 83 f1 05 xor ecx, 5
169-
# nextln: 00001e: 03 c1 add eax, ecx
170-
# nextln: 000020: 5d pop rbp
171-
# nextln: 000021: c3 ret
161+
# nextln: 000004: 33 c0 xor eax, eax
162+
# nextln: 000006: 66 0f 2e c8 ucomisd xmm1, xmm0
163+
# nextln: 00000a: 0f 97 c0 seta al
164+
# nextln: 00000d: 85 c0 test eax, eax
165+
# nextln: 00000f: 0f 85 03 00 00 00 jne 0x18
166+
# nextln: 000015: 48 89 f7 mov rdi, rsi
167+
# nextln: 000018: 83 f0 05 xor eax, 5
168+
# nextln: 00001b: 03 c7 add eax, edi
169+
# nextln: 00001d: 5d pop rbp
170+
# nextln: 00001e: c3 ret
172171

173172
%0:ctrl, %a:f64, %b:f64, %2:i32, %3:i32 = entry
174173
%1:i32 = fcmp olt %a, %b

crates/filetests/cases/codegen/icmp_brcond.spdr

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -118,17 +118,16 @@ func @select_slt_cond_reused:i32(i32, i32, i32, i32) {
118118
# check: function `select_slt_cond_reused`:
119119
# nextln: 000000: 55 push rbp
120120
# nextln: 000001: 48 89 e5 mov rbp, rsp
121-
# nextln: 000004: 48 89 d0 mov rax, rdx
122-
# nextln: 000007: 33 d2 xor edx, edx
123-
# nextln: 000009: 3b fe cmp edi, esi
124-
# nextln: 00000b: 0f 9c c2 setl dl
125-
# nextln: 00000e: 85 d2 test edx, edx
126-
# nextln: 000010: 0f 85 03 00 00 00 jne 0x19
127-
# nextln: 000016: 48 89 c8 mov rax, rcx
128-
# nextln: 000019: 83 f2 05 xor edx, 5
129-
# nextln: 00001c: 03 c2 add eax, edx
130-
# nextln: 00001e: 5d pop rbp
131-
# nextln: 00001f: c3 ret
121+
# nextln: 000004: 33 c0 xor eax, eax
122+
# nextln: 000006: 3b fe cmp edi, esi
123+
# nextln: 000008: 0f 9c c0 setl al
124+
# nextln: 00000b: 85 c0 test eax, eax
125+
# nextln: 00000d: 0f 85 03 00 00 00 jne 0x16
126+
# nextln: 000013: 48 89 ca mov rdx, rcx
127+
# nextln: 000016: 83 f0 05 xor eax, 5
128+
# nextln: 000019: 03 c2 add eax, edx
129+
# nextln: 00001b: 5d pop rbp
130+
# nextln: 00001c: c3 ret
132131

133132
%0:ctrl, %a:i32, %b:i32, %2:i32, %3:i32 = entry
134133
%1:i32 = icmp slt %a, %b

0 commit comments

Comments
 (0)