There has been occasional confusion with the representation that we use for bool-typed values in registers, at least when these are wider than one bit. Does a `b8` store `true` as 1, or as all-ones (`0xff`)? We've settled on the latter because of some use-cases where the wide bool becomes a mask -- see #2058 for more on this. This is fine, and transparent, to most operations within CLIF, because the bool-typed value still has only two semantically-visible states, namely `true` and `false`. However, we have to be careful with bool-to-int conversions. `bint` on aarch64 correctly masked the all-ones value down to 0 or 1, as required by the instruction specification, but on x64 it did not. This PR fixes that bug and makes x64 consistent with aarch64. While staring at this code I realized that `bextend` was also not consistent with the all-ones invariant: it should do a sign-extend, not a zero-extend as it previously did. This is also rectified and tested. (Aarch64 also already had this case implemented correctly.) Fixes #3003.
1109 lines
25 KiB
Plaintext
1109 lines
25 KiB
Plaintext
test compile
|
|
set enable_llvm_abi_extensions=true
|
|
target x86_64 machinst
|
|
|
|
function %f0(i128, i128) -> i128 {
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
|
|
block0(v0: i128, v1: i128):
|
|
|
|
v2 = iadd v0, v1
|
|
; nextln: addq %rdx, %rdi
|
|
; nextln: adcq %rcx, %rsi
|
|
|
|
return v2
|
|
; nextln: movq %rdi, %rax
|
|
; nextln: movq %rsi, %rdx
|
|
; nextln: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
}
|
|
|
|
function %f1(i128, i128) -> i128 {
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
|
|
block0(v0: i128, v1: i128):
|
|
|
|
v2 = isub v0, v1
|
|
; nextln: subq %rdx, %rdi
|
|
; nextln: sbbq %rcx, %rsi
|
|
|
|
return v2
|
|
; nextln: movq %rdi, %rax
|
|
; nextln: movq %rsi, %rdx
|
|
; nextln: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
}
|
|
|
|
function %f2(i128, i128) -> i128 {
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
|
|
block0(v0: i128, v1: i128):
|
|
|
|
v2 = band v0, v1
|
|
; nextln: andq %rdx, %rdi
|
|
; nextln: andq %rcx, %rsi
|
|
|
|
return v2
|
|
; nextln: movq %rdi, %rax
|
|
; nextln: movq %rsi, %rdx
|
|
; nextln: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
}
|
|
|
|
function %f3(i128, i128) -> i128 {
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
|
|
block0(v0: i128, v1: i128):
|
|
|
|
v2 = bor v0, v1
|
|
; nextln: orq %rdx, %rdi
|
|
; nextln: orq %rcx, %rsi
|
|
|
|
return v2
|
|
; nextln: movq %rdi, %rax
|
|
; nextln: movq %rsi, %rdx
|
|
; nextln: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
}
|
|
|
|
function %f4(i128, i128) -> i128 {
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
|
|
block0(v0: i128, v1: i128):
|
|
|
|
v2 = bxor v0, v1
|
|
; nextln: xorq %rdx, %rdi
|
|
; nextln: xorq %rcx, %rsi
|
|
|
|
return v2
|
|
; nextln: movq %rdi, %rax
|
|
; nextln: movq %rsi, %rdx
|
|
; nextln: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
}
|
|
|
|
function %f5(i128) -> i128 {
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
|
|
block0(v0: i128):
|
|
|
|
v1 = bnot v0
|
|
; nextln: notq %rdi
|
|
; nextln: notq %rsi
|
|
|
|
return v1
|
|
; nextln: movq %rdi, %rax
|
|
; nextln: movq %rsi, %rdx
|
|
; nextln: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
}
|
|
|
|
function %f6(i128, i128) -> i128 {
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
|
|
block0(v0: i128, v1: i128):
|
|
; v0 in rdi:rsi, v1 in rdx:rcx
|
|
|
|
v2 = imul v0, v1
|
|
; nextln: movq %rsi, %rax
|
|
; nextln: movq %rcx, %r8
|
|
; nextln: movq %rdi, %rsi
|
|
; nextln: imulq %rdx, %rsi
|
|
; nextln: movq %rdi, %rcx
|
|
; nextln: imulq %r8, %rcx
|
|
; nextln: imulq %rdx, %rax
|
|
; nextln: addq %rax, %rcx
|
|
; nextln: movq %rdi, %rax
|
|
; nextln: mul %rdx
|
|
; nextln: addq %rdx, %rcx
|
|
; nextln: movq %rsi, %rax
|
|
; nextln: movq %rcx, %rdx
|
|
|
|
return v2
|
|
; nextln: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
}
|
|
|
|
function %f7(i64, i64) -> i128 {
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
|
|
block0(v0: i64, v1: i64):
|
|
v2 = iconcat.i64 v0, v1
|
|
; nextln: movq %rdi, %rax
|
|
; nextln: movq %rsi, %rdx
|
|
|
|
return v2
|
|
; nextln: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
}
|
|
|
|
function %f8(i128) -> i64, i64 {
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
|
|
block0(v0: i128):
|
|
v1, v2 = isplit.i128 v0
|
|
; nextln: movq %rdi, %rax
|
|
; nextln: movq %rsi, %rdx
|
|
|
|
return v1, v2
|
|
; nextln: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
}
|
|
|
|
function %f9(i128, i128) -> b1 {
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
|
|
block0(v0: i128, v1: i128):
|
|
v2 = icmp eq v0, v1
|
|
; check: cmpq %rcx, %rsi
|
|
; nextln: setz %al
|
|
; nextln: cmpq %rdx, %rdi
|
|
; nextln: setz %r8b
|
|
; nextln: andq %rax, %r8
|
|
; nextln: andq $$1, %r8
|
|
; nextln: setnz %al
|
|
|
|
v3 = icmp ne v0, v1
|
|
; check: cmpq %rcx, %rsi
|
|
; nextln: setnz %al
|
|
; nextln: cmpq %rdx, %rdi
|
|
; nextln: setnz %r8b
|
|
; nextln: orq %rax, %r8
|
|
; nextln: andq $$1, %r8
|
|
; nextln: setnz %r8b
|
|
|
|
v4 = icmp slt v0, v1
|
|
; check: cmpq %rcx, %rsi
|
|
; nextln: setl %r9b
|
|
; nextln: setz %al
|
|
; nextln: cmpq %rdx, %rdi
|
|
; nextln: setb %r10b
|
|
; nextln: andq %rax, %r10
|
|
; nextln: orq %r9, %r10
|
|
; nextln: andq $$1, %r10
|
|
; nextln: setnz %r9b
|
|
|
|
v5 = icmp sle v0, v1
|
|
; check: cmpq %rcx, %rsi
|
|
; nextln: setl %r10b
|
|
; nextln: setz %al
|
|
; nextln: cmpq %rdx, %rdi
|
|
; nextln: setbe %r11b
|
|
; nextln: andq %rax, %r11
|
|
; nextln: orq %r10, %r11
|
|
; nextln: andq $$1, %r11
|
|
; nextln: setnz %r10b
|
|
|
|
v6 = icmp sgt v0, v1
|
|
; check: cmpq %rcx, %rsi
|
|
; nextln: setnle %r11b
|
|
; nextln: setz %al
|
|
; nextln: cmpq %rdx, %rdi
|
|
; nextln: setnbe %r12b
|
|
; nextln: andq %rax, %r12
|
|
; nextln: orq %r11, %r12
|
|
; nextln: andq $$1, %r12
|
|
; nextln: setnz %r11b
|
|
|
|
v7 = icmp sge v0, v1
|
|
; check: cmpq %rcx, %rsi
|
|
; nextln: setnle %r12b
|
|
; nextln: setz %al
|
|
; nextln: cmpq %rdx, %rdi
|
|
; nextln: setnb %r13b
|
|
; nextln: andq %rax, %r13
|
|
; nextln: orq %r12, %r13
|
|
; nextln: andq $$1, %r13
|
|
; nextln: setnz %r12b
|
|
|
|
v8 = icmp ult v0, v1
|
|
; check: cmpq %rcx, %rsi
|
|
; nextln: setb %r13b
|
|
; nextln: setz %al
|
|
; nextln: cmpq %rdx, %rdi
|
|
; nextln: setb %r14b
|
|
; nextln: andq %rax, %r14
|
|
; nextln: orq %r13, %r14
|
|
; nextln: andq $$1, %r14
|
|
; nextln: setnz %r13b
|
|
|
|
v9 = icmp ule v0, v1
|
|
; check: cmpq %rcx, %rsi
|
|
; nextln: setb %r14b
|
|
; nextln: setz %al
|
|
; nextln: cmpq %rdx, %rdi
|
|
; nextln: setbe %bl
|
|
; nextln: andq %rax, %rbx
|
|
; nextln: orq %r14, %rbx
|
|
; nextln: andq $$1, %rbx
|
|
; nextln: setnz %r14b
|
|
|
|
v10 = icmp ugt v0, v1
|
|
; check: cmpq %rcx, %rsi
|
|
; nextln: setnbe %bl
|
|
; nextln: setz %r15b
|
|
; nextln: cmpq %rdx, %rdi
|
|
; nextln: setnbe %al
|
|
; nextln: andq %r15, %rax
|
|
; nextln: orq %rbx, %rax
|
|
; nextln: andq $$1, %rax
|
|
; nextln: setnz %bl
|
|
|
|
v11 = icmp uge v0, v1
|
|
; check: cmpq %rcx, %rsi
|
|
; nextln: setnbe %sil
|
|
; nextln: setz %cl
|
|
; nextln: cmpq %rdx, %rdi
|
|
; nextln: setnb %dil
|
|
; nextln: andq %rcx, %rdi
|
|
; nextln: orq %rsi, %rdi
|
|
; nextln: andq $$1, %rdi
|
|
; nextln: setnz %sil
|
|
|
|
v12 = band v2, v3
|
|
v13 = band v4, v5
|
|
v14 = band v6, v7
|
|
v15 = band v8, v9
|
|
v16 = band v10, v11
|
|
v17 = band v12, v13
|
|
v18 = band v14, v15
|
|
v19 = band v17, v18
|
|
v20 = band v19, v16
|
|
|
|
return v20
|
|
; check: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
}
|
|
|
|
function %f10(i128) -> i32 {
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
|
|
block0(v0: i128):
|
|
brz v0, block1
|
|
; check: cmpq $$0, %rdi
|
|
; nextln: setz %dil
|
|
; nextln: cmpq $$0, %rsi
|
|
; nextln: setz %sil
|
|
; nextln: andb %dil, %sil
|
|
; nextln: jnz label1; j label2
|
|
|
|
jump block2
|
|
|
|
block1:
|
|
v1 = iconst.i32 1
|
|
return v1
|
|
|
|
block2:
|
|
v2 = iconst.i32 2
|
|
return v2
|
|
|
|
; check: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
}
|
|
|
|
function %f11(i128) -> i32 {
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
|
|
block0(v0: i128):
|
|
brnz v0, block1
|
|
; check: cmpq $$0, %rdi
|
|
; nextln: setnz %dil
|
|
; nextln: cmpq $$0, %rsi
|
|
; nextln: setnz %sil
|
|
; nextln: orb %dil, %sil
|
|
; nextln: jnz label1; j label2
|
|
jump block2
|
|
|
|
block1:
|
|
v1 = iconst.i32 1
|
|
return v1
|
|
|
|
block2:
|
|
v2 = iconst.i32 2
|
|
return v2
|
|
|
|
; check: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
}
|
|
|
|
function %f12(i64) -> i128 {
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
|
|
block0(v0: i64):
|
|
v1 = uextend.i128 v0
|
|
return v1
|
|
|
|
; nextln: movq %rdi, %rsi
|
|
; nextln: xorq %rdi, %rdi
|
|
; nextln: movq %rsi, %rax
|
|
; nextln: movq %rdi, %rdx
|
|
|
|
; nextln: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
}
|
|
|
|
function %f13(i64) -> i128 {
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
|
|
block0(v0: i64):
|
|
v1 = sextend.i128 v0
|
|
return v1
|
|
|
|
; nextln: movq %rdi, %rsi
|
|
; nextln: movq %rsi, %rdi
|
|
; nextln: sarq $$63, %rdi
|
|
; nextln: movq %rsi, %rax
|
|
; nextln: movq %rdi, %rdx
|
|
|
|
; nextln: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
}
|
|
|
|
function %f14(i8) -> i128 {
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
|
|
block0(v0: i8):
|
|
v1 = sextend.i128 v0
|
|
return v1
|
|
|
|
; nextln: movsbq %dil, %rsi
|
|
; nextln: movq %rsi, %rdi
|
|
; nextln: sarq $$63, %rdi
|
|
; nextln: movq %rsi, %rax
|
|
; nextln: movq %rdi, %rdx
|
|
|
|
; nextln: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
}
|
|
|
|
function %f15(i8) -> i128 {
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
|
|
block0(v0: i8):
|
|
v1 = uextend.i128 v0
|
|
return v1
|
|
|
|
; nextln: movzbq %dil, %rsi
|
|
; nextln: xorq %rdi, %rdi
|
|
; nextln: movq %rsi, %rax
|
|
; nextln: movq %rdi, %rdx
|
|
|
|
; nextln: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
|
|
}
|
|
|
|
function %f16(i128) -> i64 {
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
|
|
block0(v0: i128):
|
|
v1 = ireduce.i64 v0
|
|
return v1
|
|
|
|
; nextln: movq %rdi, %rax
|
|
|
|
; nextln: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
}
|
|
|
|
function %f17(i128) -> i8 {
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
|
|
block0(v0: i128):
|
|
v1 = ireduce.i8 v0
|
|
return v1
|
|
|
|
; nextln: movq %rdi, %rax
|
|
|
|
; nextln: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
}
|
|
|
|
function %f18(b1) -> i128 {
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
|
|
block0(v0: b1):
|
|
v1 = bint.i128 v0
|
|
return v1
|
|
|
|
; nextln: movq %rdi, %rsi
|
|
; nextln: andq $$1, %rsi
|
|
; nextln: xorq %rdi, %rdi
|
|
; nextln: movq %rsi, %rax
|
|
; nextln: movq %rdi, %rdx
|
|
|
|
; nextln: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
}
|
|
|
|
function %f19(i128) -> i128 {
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
|
|
block0(v0: i128):
|
|
v1 = popcnt.i128 v0
|
|
return v1
|
|
|
|
; check: movq %rsi, %rdx
|
|
; nextln: movq %rdi, %rsi
|
|
; nextln: shrq $$1, %rsi
|
|
; nextln: movabsq $$8608480567731124087, %rcx
|
|
; nextln: andq %rcx, %rsi
|
|
; nextln: movq %rdi, %rax
|
|
; nextln: subq %rsi, %rax
|
|
; nextln: shrq $$1, %rsi
|
|
; nextln: andq %rcx, %rsi
|
|
; nextln: subq %rsi, %rax
|
|
; nextln: shrq $$1, %rsi
|
|
; nextln: andq %rcx, %rsi
|
|
; nextln: subq %rsi, %rax
|
|
; nextln: movq %rax, %rsi
|
|
; nextln: shrq $$4, %rsi
|
|
; nextln: addq %rax, %rsi
|
|
; nextln: movabsq $$1085102592571150095, %rdi
|
|
; nextln: andq %rdi, %rsi
|
|
; nextln: movabsq $$72340172838076673, %rdi
|
|
; nextln: imulq %rdi, %rsi
|
|
; nextln: shrq $$56, %rsi
|
|
; nextln: movq %rdx, %rax
|
|
; nextln: shrq $$1, %rax
|
|
; nextln: movabsq $$8608480567731124087, %rcx
|
|
; nextln: andq %rcx, %rax
|
|
; nextln: movq %rdx, %rdi
|
|
; nextln: subq %rax, %rdi
|
|
; nextln: shrq $$1, %rax
|
|
; nextln: andq %rcx, %rax
|
|
; nextln: subq %rax, %rdi
|
|
; nextln: shrq $$1, %rax
|
|
; nextln: andq %rcx, %rax
|
|
; nextln: subq %rax, %rdi
|
|
; nextln: movq %rdi, %rax
|
|
; nextln: shrq $$4, %rax
|
|
; nextln: addq %rdi, %rax
|
|
; nextln: movabsq $$1085102592571150095, %rdi
|
|
; nextln: andq %rdi, %rax
|
|
; nextln: movabsq $$72340172838076673, %rdi
|
|
; nextln: imulq %rdi, %rax
|
|
; nextln: shrq $$56, %rax
|
|
; nextln: addq %rax, %rsi
|
|
; nextln: xorq %rdi, %rdi
|
|
; nextln: movq %rsi, %rax
|
|
; nextln: movq %rdi, %rdx
|
|
|
|
|
|
; nextln: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
}
|
|
|
|
|
|
function %f20(i128) -> i128 {
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
|
|
block0(v0: i128):
|
|
v1 = bitrev.i128 v0
|
|
return v1
|
|
|
|
; check: movq %rdi, %rcx
|
|
; nextln: movq %rcx, %rdi
|
|
; nextln: movabsq $$6148914691236517205, %rax
|
|
; nextln: shrq $$1, %rdi
|
|
; nextln: andq %rax, %rdi
|
|
; nextln: andq %rcx, %rax
|
|
; nextln: shlq $$1, %rax
|
|
; nextln: movq %rax, %rcx
|
|
; nextln: orq %rdi, %rcx
|
|
; nextln: movq %rcx, %rdi
|
|
; nextln: movabsq $$3689348814741910323, %rax
|
|
; nextln: shrq $$2, %rdi
|
|
; nextln: andq %rax, %rdi
|
|
; nextln: andq %rcx, %rax
|
|
; nextln: shlq $$2, %rax
|
|
; nextln: movq %rax, %rcx
|
|
; nextln: orq %rdi, %rcx
|
|
; nextln: movq %rcx, %rdi
|
|
; nextln: movabsq $$1085102592571150095, %rax
|
|
; nextln: shrq $$4, %rdi
|
|
; nextln: andq %rax, %rdi
|
|
; nextln: andq %rcx, %rax
|
|
; nextln: shlq $$4, %rax
|
|
; nextln: movq %rax, %rcx
|
|
; nextln: orq %rdi, %rcx
|
|
; nextln: movq %rcx, %rdi
|
|
; nextln: movabsq $$71777214294589695, %rax
|
|
; nextln: shrq $$8, %rdi
|
|
; nextln: andq %rax, %rdi
|
|
; nextln: andq %rcx, %rax
|
|
; nextln: shlq $$8, %rax
|
|
; nextln: movq %rax, %rcx
|
|
; nextln: orq %rdi, %rcx
|
|
; nextln: movq %rcx, %rdi
|
|
; nextln: movabsq $$281470681808895, %rax
|
|
; nextln: shrq $$16, %rdi
|
|
; nextln: andq %rax, %rdi
|
|
; nextln: andq %rcx, %rax
|
|
; nextln: shlq $$16, %rax
|
|
; nextln: orq %rdi, %rax
|
|
; nextln: movq %rax, %rcx
|
|
; nextln: movl $$-1, %edi
|
|
; nextln: shrq $$32, %rcx
|
|
; nextln: andq %rdi, %rcx
|
|
; nextln: andq %rax, %rdi
|
|
; nextln: shlq $$32, %rdi
|
|
; nextln: orq %rcx, %rdi
|
|
; nextln: movq %rsi, %rcx
|
|
; nextln: movq %rcx, %rsi
|
|
; nextln: movabsq $$6148914691236517205, %rax
|
|
; nextln: shrq $$1, %rsi
|
|
; nextln: andq %rax, %rsi
|
|
; nextln: andq %rcx, %rax
|
|
; nextln: shlq $$1, %rax
|
|
; nextln: movq %rax, %rcx
|
|
; nextln: orq %rsi, %rcx
|
|
; nextln: movq %rcx, %rsi
|
|
; nextln: movabsq $$3689348814741910323, %rax
|
|
; nextln: shrq $$2, %rsi
|
|
; nextln: andq %rax, %rsi
|
|
; nextln: andq %rcx, %rax
|
|
; nextln: shlq $$2, %rax
|
|
; nextln: movq %rax, %rcx
|
|
; nextln: orq %rsi, %rcx
|
|
; nextln: movq %rcx, %rsi
|
|
; nextln: movabsq $$1085102592571150095, %rax
|
|
; nextln: shrq $$4, %rsi
|
|
; nextln: andq %rax, %rsi
|
|
; nextln: andq %rcx, %rax
|
|
; nextln: shlq $$4, %rax
|
|
; nextln: movq %rax, %rcx
|
|
; nextln: orq %rsi, %rcx
|
|
; nextln: movq %rcx, %rsi
|
|
; nextln: movabsq $$71777214294589695, %rax
|
|
; nextln: shrq $$8, %rsi
|
|
; nextln: andq %rax, %rsi
|
|
; nextln: andq %rcx, %rax
|
|
; nextln: shlq $$8, %rax
|
|
; nextln: movq %rax, %rcx
|
|
; nextln: orq %rsi, %rcx
|
|
; nextln: movq %rcx, %rsi
|
|
; nextln: movabsq $$281470681808895, %rax
|
|
; nextln: shrq $$16, %rsi
|
|
; nextln: andq %rax, %rsi
|
|
; nextln: andq %rcx, %rax
|
|
; nextln: shlq $$16, %rax
|
|
; nextln: orq %rsi, %rax
|
|
; nextln: movq %rax, %rsi
|
|
; nextln: movl $$-1, %ecx
|
|
; nextln: shrq $$32, %rsi
|
|
; nextln: andq %rcx, %rsi
|
|
; nextln: andq %rax, %rcx
|
|
; nextln: shlq $$32, %rcx
|
|
; nextln: orq %rsi, %rcx
|
|
; nextln: movq %rcx, %rax
|
|
; nextln: movq %rdi, %rdx
|
|
|
|
; nextln: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
}
|
|
|
|
; Shifts are covered by run-tests in shift-i128-run.clif.
|
|
|
|
function %f21(i128, i64) {
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
|
|
block0(v0: i128, v1: i64):
|
|
store.i128 v0, v1
|
|
return
|
|
|
|
; check: movq %rdi, 0(%rdx)
|
|
; nextln: movq %rsi, 8(%rdx)
|
|
|
|
; nextln: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
}
|
|
|
|
function %f22(i64) -> i128 {
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
|
|
block0(v0: i64):
|
|
v1 = load.i128 v0
|
|
return v1
|
|
|
|
; check: movq 0(%rdi), %rsi
|
|
; nextln: movq 8(%rdi), %rdi
|
|
; nextln: movq %rsi, %rax
|
|
; nextln: movq %rdi, %rdx
|
|
|
|
; nextln: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
}
|
|
|
|
function %f23(i128, b1) -> i128 {
|
|
block0(v0: i128, v1: b1):
|
|
v2 = iconst.i128 0
|
|
brnz v1, block1(v2)
|
|
jump block2(v2)
|
|
|
|
block1(v3: i128):
|
|
v4 = iconst.i128 1
|
|
v5 = iadd.i128 v3, v4
|
|
return v5
|
|
|
|
block2(v6: i128):
|
|
v7 = iconst.i128 2
|
|
v8 = iadd.i128 v6, v7
|
|
return v8
|
|
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
; nextln: testb $$1, %dl
|
|
; nextln: jnz label1; j label2
|
|
; check: Block 1:
|
|
; check: movl $$0, %esi
|
|
; nextln: movl $$0, %edi
|
|
; nextln: movl $$1, %eax
|
|
; nextln: movl $$0, %ecx
|
|
; nextln: addq %rax, %rsi
|
|
; nextln: adcq %rcx, %rdi
|
|
; nextln: movq %rsi, %rax
|
|
; nextln: movq %rdi, %rdx
|
|
; nextln: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
; check: Block 2:
|
|
; check: movl $$0, %esi
|
|
; nextln: movl $$0, %edi
|
|
; nextln: movl $$2, %eax
|
|
; nextln: movl $$0, %ecx
|
|
; nextln: addq %rax, %rsi
|
|
; nextln: adcq %rcx, %rdi
|
|
; nextln: movq %rsi, %rax
|
|
; nextln: movq %rdi, %rdx
|
|
; nextln: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
|
|
}
|
|
|
|
function %f24(i128, i128, i64, i128, i128, i128) -> i128 {
|
|
|
|
block0(v0: i128, v1: i128, v2: i64, v3: i128, v4: i128, v5: i128):
|
|
v6 = iadd.i128 v0, v1
|
|
v7 = uextend.i128 v2
|
|
v8 = iadd.i128 v3, v7
|
|
v9 = iadd.i128 v4, v5
|
|
v10 = iadd.i128 v6, v8
|
|
v11 = iadd.i128 v9, v10
|
|
return v11
|
|
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
; nextln: subq $$16, %rsp
|
|
; nextln: movq %r12, 0(%rsp)
|
|
; nextln: movq %r13, 8(%rsp)
|
|
; nextln: movq 16(%rbp), %r10
|
|
; nextln: movq 24(%rbp), %r12
|
|
; nextln: movq 32(%rbp), %r11
|
|
; nextln: movq 40(%rbp), %rax
|
|
; nextln: movq 48(%rbp), %r13
|
|
; nextln: addq %rdx, %rdi
|
|
; nextln: adcq %rcx, %rsi
|
|
; nextln: xorq %rcx, %rcx
|
|
; nextln: addq %r8, %r9
|
|
; nextln: adcq %rcx, %r10
|
|
; nextln: addq %rax, %r12
|
|
; nextln: adcq %r13, %r11
|
|
; nextln: addq %r9, %rdi
|
|
; nextln: adcq %r10, %rsi
|
|
; nextln: addq %rdi, %r12
|
|
; nextln: adcq %rsi, %r11
|
|
; nextln: movq %r12, %rax
|
|
; nextln: movq %r11, %rdx
|
|
; nextln: movq 0(%rsp), %r12
|
|
; nextln: movq 8(%rsp), %r13
|
|
; nextln: addq $$16, %rsp
|
|
; nextln: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
|
|
}
|
|
|
|
function %f25(i128) -> i128, i128, i128, i64, i128, i128 {
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
|
|
block0(v0: i128):
|
|
v1 = ireduce.i64 v0
|
|
return v0, v0, v0, v1, v0, v0
|
|
|
|
; likely to change with regalloc -- just check the stores into the retval area:
|
|
|
|
; check: movq %r8, 0(%rsi)
|
|
; nextln: movq %r9, 8(%rsi)
|
|
; nextln: movq %r10, 16(%rsi)
|
|
; nextln: movq %r11, 24(%rsi)
|
|
; nextln: movq %r12, 32(%rsi)
|
|
; nextln: movq %r13, 40(%rsi)
|
|
; nextln: movq %r14, 48(%rsi)
|
|
; nextln: movq %rdi, 56(%rsi)
|
|
; nextln: movq %rbx, 64(%rsi)
|
|
|
|
}
|
|
|
|
function %f26(i128, i128) -> i128, i128 {
|
|
fn0 = %g(i128, i128) -> i128, i128
|
|
block0(v0: i128, v1: i128):
|
|
v2, v3 = call fn0(v0, v1)
|
|
return v2, v3
|
|
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
; nextln: subq $$16, %rsp
|
|
; nextln: movq %r12, 0(%rsp)
|
|
; nextln: movq %r8, %r12
|
|
; nextln: subq $$16, %rsp
|
|
; nextln: virtual_sp_offset_adjust 16
|
|
; nextln: lea 0(%rsp), %r8
|
|
; nextln: load_ext_name %g+0, %rax
|
|
; nextln: call *%rax
|
|
; nextln: movq 0(%rsp), %rsi
|
|
; nextln: movq 8(%rsp), %rdi
|
|
; nextln: addq $$16, %rsp
|
|
; nextln: virtual_sp_offset_adjust -16
|
|
; nextln: movq %rsi, 0(%r12)
|
|
; nextln: movq %rdi, 8(%r12)
|
|
; nextln: movq 0(%rsp), %r12
|
|
; nextln: addq $$16, %rsp
|
|
; nextln: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
|
|
}
|
|
|
|
function %f27(i128) -> i128 {
|
|
block0(v0: i128):
|
|
v1 = clz.i128 v0
|
|
return v1
|
|
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
; nextln: movabsq $$-1, %rcx
|
|
; nextln: bsrq %rsi, %rax
|
|
; nextln: cmovzq %rcx, %rax
|
|
; nextln: movl $$63, %esi
|
|
; nextln: subq %rax, %rsi
|
|
; nextln: movabsq $$-1, %rcx
|
|
; nextln: bsrq %rdi, %rax
|
|
; nextln: cmovzq %rcx, %rax
|
|
; nextln: movl $$63, %edi
|
|
; nextln: subq %rax, %rdi
|
|
; nextln: addq $$64, %rdi
|
|
; nextln: cmpq $$64, %rsi
|
|
; nextln: cmovnzq %rsi, %rdi
|
|
; nextln: xorq %rsi, %rsi
|
|
; nextln: movq %rdi, %rax
|
|
; nextln: movq %rsi, %rdx
|
|
; nextln: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
|
|
}
|
|
|
|
function %f28(i128) -> i128 {
|
|
block0(v0: i128):
|
|
v1 = ctz.i128 v0
|
|
return v1
|
|
}
|
|
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
; nextln: movq %rsi, %rax
|
|
; nextln: movl $$64, %ecx
|
|
; nextln: bsfq %rdi, %rsi
|
|
; nextln: cmovzq %rcx, %rsi
|
|
; nextln: movl $$64, %ecx
|
|
; nextln: bsfq %rax, %rdi
|
|
; nextln: cmovzq %rcx, %rdi
|
|
; nextln: addq $$64, %rdi
|
|
; nextln: cmpq $$64, %rsi
|
|
; nextln: cmovzq %rdi, %rsi
|
|
; nextln: xorq %rdi, %rdi
|
|
; nextln: movq %rsi, %rax
|
|
; nextln: movq %rdi, %rdx
|
|
; nextln: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
|
|
function %f29(i8, i128) -> i8 {
|
|
block0(v0: i8, v1: i128):
|
|
v2 = ishl v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
; nextln: movq %rsi, %rcx
|
|
; nextln: shll %cl, %edi
|
|
; nextln: movq %rdi, %rax
|
|
; nextln: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
|
|
function %f30(i128, i128) -> i128 {
|
|
block0(v0: i128, v1: i128):
|
|
v2 = ishl v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
; nextln: movq %rsi, %rax
|
|
; nextln: movq %rdi, %rsi
|
|
; nextln: movq %rdx, %rcx
|
|
; nextln: shlq %cl, %rsi
|
|
; nextln: movq %rdx, %rcx
|
|
; nextln: shlq %cl, %rax
|
|
; nextln: movl $$64, %ecx
|
|
; nextln: subq %rdx, %rcx
|
|
; nextln: shrq %cl, %rdi
|
|
; nextln: xorq %rcx, %rcx
|
|
; nextln: testq $$127, %rdx
|
|
; nextln: cmovzq %rcx, %rdi
|
|
; nextln: orq %rax, %rdi
|
|
; nextln: xorq %rax, %rax
|
|
; nextln: andq $$64, %rdx
|
|
; nextln: cmovzq %rdi, %rax
|
|
; nextln: cmovzq %rsi, %rcx
|
|
; nextln: cmovnzq %rsi, %rax
|
|
; nextln: movq %rax, %rdx
|
|
; nextln: movq %rcx, %rax
|
|
; nextln: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
|
|
function %f31(i128, i128) -> i128 {
|
|
block0(v0: i128, v1: i128):
|
|
v2 = ushr v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
; nextln: movq %rdi, %rax
|
|
; nextln: movq %rsi, %rdi
|
|
; nextln: movq %rdi, %rsi
|
|
; nextln: movq %rdx, %rcx
|
|
; nextln: shrq %cl, %rsi
|
|
; nextln: movq %rdx, %rcx
|
|
; nextln: shrq %cl, %rax
|
|
; nextln: movl $$64, %ecx
|
|
; nextln: subq %rdx, %rcx
|
|
; nextln: shlq %cl, %rdi
|
|
; nextln: xorq %rcx, %rcx
|
|
; nextln: testq $$127, %rdx
|
|
; nextln: cmovzq %rcx, %rdi
|
|
; nextln: orq %rax, %rdi
|
|
; nextln: xorq %rax, %rax
|
|
; nextln: xorq %rcx, %rcx
|
|
; nextln: andq $$64, %rdx
|
|
; nextln: cmovzq %rsi, %rax
|
|
; nextln: cmovzq %rdi, %rcx
|
|
; nextln: cmovnzq %rsi, %rcx
|
|
; nextln: movq %rax, %rdx
|
|
; nextln: movq %rcx, %rax
|
|
; nextln: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
|
|
function %f32(i128, i128) -> i128 {
|
|
block0(v0: i128, v1: i128):
|
|
v2 = sshr v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
; nextln: movq %rdi, %r8
|
|
; nextln: movq %rsi, %rdi
|
|
; nextln: movq %rdi, %rsi
|
|
; nextln: movq %rdx, %rcx
|
|
; nextln: sarq %cl, %rsi
|
|
; nextln: movq %rdx, %rcx
|
|
; nextln: shrq %cl, %r8
|
|
; nextln: movl $$64, %ecx
|
|
; nextln: subq %rdx, %rcx
|
|
; nextln: movq %rdi, %rax
|
|
; nextln: shlq %cl, %rax
|
|
; nextln: xorq %rcx, %rcx
|
|
; nextln: testq $$127, %rdx
|
|
; nextln: cmovzq %rcx, %rax
|
|
; nextln: orq %r8, %rax
|
|
; nextln: sarq $$63, %rdi
|
|
; nextln: xorq %rcx, %rcx
|
|
; nextln: andq $$64, %rdx
|
|
; nextln: cmovzq %rsi, %rdi
|
|
; nextln: cmovzq %rax, %rcx
|
|
; nextln: cmovnzq %rsi, %rcx
|
|
; nextln: movq %rcx, %rax
|
|
; nextln: movq %rdi, %rdx
|
|
; nextln: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
|
|
function %f33(i128, i128) -> i128 {
|
|
block0(v0: i128, v1: i128):
|
|
v2 = rotl v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
; nextln: movq %rdi, %r8
|
|
; nextln: movq %r8, %r9
|
|
; nextln: movq %rdx, %rcx
|
|
; nextln: shlq %cl, %r9
|
|
; nextln: movq %rsi, %rax
|
|
; nextln: movq %rdx, %rcx
|
|
; nextln: shlq %cl, %rax
|
|
; nextln: movl $$64, %ecx
|
|
; nextln: subq %rdx, %rcx
|
|
; nextln: movq %r8, %r10
|
|
; nextln: shrq %cl, %r10
|
|
; nextln: xorq %rdi, %rdi
|
|
; nextln: testq $$127, %rdx
|
|
; nextln: cmovzq %rdi, %r10
|
|
; nextln: orq %rax, %r10
|
|
; nextln: xorq %rax, %rax
|
|
; nextln: movq %rdx, %rcx
|
|
; nextln: andq $$64, %rcx
|
|
; nextln: cmovzq %r10, %rax
|
|
; nextln: cmovzq %r9, %rdi
|
|
; nextln: cmovnzq %r9, %rax
|
|
; nextln: movl $$128, %r9d
|
|
; nextln: subq %rdx, %r9
|
|
; nextln: movq %rsi, %rdx
|
|
; nextln: movq %r9, %rcx
|
|
; nextln: shrq %cl, %rdx
|
|
; nextln: movq %r9, %rcx
|
|
; nextln: shrq %cl, %r8
|
|
; nextln: movl $$64, %ecx
|
|
; nextln: subq %r9, %rcx
|
|
; nextln: shlq %cl, %rsi
|
|
; nextln: xorq %rcx, %rcx
|
|
; nextln: testq $$127, %r9
|
|
; nextln: cmovzq %rcx, %rsi
|
|
; nextln: orq %r8, %rsi
|
|
; nextln: xorq %rcx, %rcx
|
|
; nextln: xorq %r8, %r8
|
|
; nextln: andq $$64, %r9
|
|
; nextln: cmovzq %rdx, %rcx
|
|
; nextln: cmovzq %rsi, %r8
|
|
; nextln: cmovnzq %rdx, %r8
|
|
; nextln: orq %rdi, %r8
|
|
; nextln: orq %rax, %rcx
|
|
; nextln: movq %r8, %rax
|
|
; nextln: movq %rcx, %rdx
|
|
; nextln: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret
|
|
|
|
|
|
function %f34(i128, i128) -> i128 {
|
|
block0(v0: i128, v1: i128):
|
|
v2 = rotr v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: pushq %rbp
|
|
; nextln: movq %rsp, %rbp
|
|
; nextln: movq %rsi, %r9
|
|
; nextln: movq %rdx, %rcx
|
|
; nextln: shrq %cl, %r9
|
|
; nextln: movq %rdi, %rax
|
|
; nextln: movq %rdx, %rcx
|
|
; nextln: shrq %cl, %rax
|
|
; nextln: movl $$64, %ecx
|
|
; nextln: subq %rdx, %rcx
|
|
; nextln: movq %rsi, %r10
|
|
; nextln: shlq %cl, %r10
|
|
; nextln: xorq %rcx, %rcx
|
|
; nextln: testq $$127, %rdx
|
|
; nextln: cmovzq %rcx, %r10
|
|
; nextln: orq %rax, %r10
|
|
; nextln: xorq %rax, %rax
|
|
; nextln: xorq %r8, %r8
|
|
; nextln: movq %rdx, %rcx
|
|
; nextln: andq $$64, %rcx
|
|
; nextln: cmovzq %r9, %rax
|
|
; nextln: cmovzq %r10, %r8
|
|
; nextln: cmovnzq %r9, %r8
|
|
; nextln: movl $$128, %r9d
|
|
; nextln: subq %rdx, %r9
|
|
; nextln: movq %rdi, %rdx
|
|
; nextln: movq %r9, %rcx
|
|
; nextln: shlq %cl, %rdx
|
|
; nextln: movq %rsi, %r10
|
|
; nextln: movq %r9, %rcx
|
|
; nextln: shlq %cl, %r10
|
|
; nextln: movl $$64, %ecx
|
|
; nextln: subq %r9, %rcx
|
|
; nextln: shrq %cl, %rdi
|
|
; nextln: xorq %rsi, %rsi
|
|
; nextln: testq $$127, %r9
|
|
; nextln: cmovzq %rsi, %rdi
|
|
; nextln: orq %r10, %rdi
|
|
; nextln: xorq %rcx, %rcx
|
|
; nextln: andq $$64, %r9
|
|
; nextln: cmovzq %rdi, %rcx
|
|
; nextln: cmovzq %rdx, %rsi
|
|
; nextln: cmovnzq %rdx, %rcx
|
|
; nextln: orq %r8, %rsi
|
|
; nextln: orq %rax, %rcx
|
|
; nextln: movq %rsi, %rax
|
|
; nextln: movq %rcx, %rdx
|
|
; nextln: movq %rbp, %rsp
|
|
; nextln: popq %rbp
|
|
; nextln: ret |