This adds ISLE support for the s390x back-end and moves lowering of most instructions to ISLE. The only instructions still remaining are calls, returns, traps, and branches, most of which will need additional support in common code. Generated code is not intended to be (significantly) different than before; any additional optimizations now made easier to implement due to the ISLE layer can be added in follow-on patches. There were a few differences in some filetests, but those are all just simple register allocation changes (and all to the better!).
456 lines
7.9 KiB
Plaintext
456 lines
7.9 KiB
Plaintext
test compile
|
|
target s390x
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; ROTR
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
function %rotr_i64_reg(i64, i64) -> i64 {
|
|
block0(v0: i64, v1: i64):
|
|
v2 = rotr.i64 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: lcgr %r3, %r3
|
|
; nextln: rllg %r2, %r2, 0(%r3)
|
|
; nextln: br %r14
|
|
|
|
function %rotr_i64_imm(i64) -> i64 {
|
|
block0(v0: i64):
|
|
v1 = iconst.i32 17
|
|
v2 = rotr.i64 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: rllg %r2, %r2, 47
|
|
; nextln: br %r14
|
|
|
|
function %rotr_i32_reg(i32, i32) -> i32 {
|
|
block0(v0: i32, v1: i32):
|
|
v2 = rotr.i32 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: lcr %r3, %r3
|
|
; nextln: rll %r2, %r2, 0(%r3)
|
|
; nextln: br %r14
|
|
|
|
function %rotr_i32_imm(i32) -> i32 {
|
|
block0(v0: i32):
|
|
v1 = iconst.i32 17
|
|
v2 = rotr.i32 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: rll %r2, %r2, 15
|
|
; nextln: br %r14
|
|
|
|
function %rotr_i16_reg(i16, i16) -> i16 {
|
|
block0(v0: i16, v1: i16):
|
|
v2 = rotr.i16 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: llhr %r2, %r2
|
|
; nextln: lcr %r4, %r3
|
|
; nextln: nill %r3, 15
|
|
; nextln: nill %r4, 15
|
|
; nextln: sllk %r4, %r2, 0(%r4)
|
|
; nextln: srlk %r2, %r2, 0(%r3)
|
|
; nextln: ork %r2, %r4, %r2
|
|
; nextln: br %r14
|
|
|
|
function %rotr_i16_imm(i16) -> i16 {
|
|
block0(v0: i16):
|
|
v1 = iconst.i32 10
|
|
v2 = rotr.i16 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: llhr %r2, %r2
|
|
; nextln: sllk %r3, %r2, 6
|
|
; nextln: srlk %r2, %r2, 10
|
|
; nextln: ork %r2, %r3, %r2
|
|
; nextln: br %r14
|
|
|
|
function %rotr_i8_reg(i8, i8) -> i8 {
|
|
block0(v0: i8, v1: i8):
|
|
v2 = rotr.i8 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: llcr %r2, %r2
|
|
; nextln: lcr %r4, %r3
|
|
; nextln: nill %r3, 7
|
|
; nextln: nill %r4, 7
|
|
; nextln: sllk %r4, %r2, 0(%r4)
|
|
; nextln: srlk %r2, %r2, 0(%r3)
|
|
; nextln: ork %r2, %r4, %r2
|
|
; nextln: br %r14
|
|
|
|
function %rotr_i8_imm(i8) -> i8 {
|
|
block0(v0: i8):
|
|
v1 = iconst.i32 3
|
|
v2 = rotr.i8 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: llcr %r2, %r2
|
|
; nextln: sllk %r3, %r2, 5
|
|
; nextln: srlk %r2, %r2, 3
|
|
; nextln: ork %r2, %r3, %r2
|
|
; nextln: br %r14
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; ROTL
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
function %rotl_i64_reg(i64, i64) -> i64 {
|
|
block0(v0: i64, v1: i64):
|
|
v2 = rotl.i64 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: rllg %r2, %r2, 0(%r3)
|
|
; nextln: br %r14
|
|
|
|
function %rotl_i64_imm(i64) -> i64 {
|
|
block0(v0: i64):
|
|
v1 = iconst.i32 17
|
|
v2 = rotl.i64 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: rllg %r2, %r2, 17
|
|
; nextln: br %r14
|
|
|
|
function %rotl_i32_reg(i32, i32) -> i32 {
|
|
block0(v0: i32, v1: i32):
|
|
v2 = rotl.i32 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: rll %r2, %r2, 0(%r3)
|
|
; nextln: br %r14
|
|
|
|
function %rotl_i32_imm(i32) -> i32 {
|
|
block0(v0: i32):
|
|
v1 = iconst.i32 17
|
|
v2 = rotl.i32 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: rll %r2, %r2, 17
|
|
; nextln: br %r14
|
|
|
|
function %rotl_i16_reg(i16, i16) -> i16 {
|
|
block0(v0: i16, v1: i16):
|
|
v2 = rotl.i16 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: llhr %r2, %r2
|
|
; nextln: lcr %r4, %r3
|
|
; nextln: nill %r3, 15
|
|
; nextln: nill %r4, 15
|
|
; nextln: sllk %r3, %r2, 0(%r3)
|
|
; nextln: srlk %r2, %r2, 0(%r4)
|
|
; nextln: ork %r2, %r3, %r2
|
|
; nextln: br %r14
|
|
|
|
function %rotl_i16_imm(i16) -> i16 {
|
|
block0(v0: i16):
|
|
v1 = iconst.i32 10
|
|
v2 = rotl.i16 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: llhr %r2, %r2
|
|
; nextln: sllk %r3, %r2, 10
|
|
; nextln: srlk %r2, %r2, 6
|
|
; nextln: ork %r2, %r3, %r2
|
|
; nextln: br %r14
|
|
|
|
function %rotl_i8_reg(i8, i8) -> i8 {
|
|
block0(v0: i8, v1: i8):
|
|
v2 = rotl.i8 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: llcr %r2, %r2
|
|
; nextln: lcr %r4, %r3
|
|
; nextln: nill %r3, 7
|
|
; nextln: nill %r4, 7
|
|
; nextln: sllk %r3, %r2, 0(%r3)
|
|
; nextln: srlk %r2, %r2, 0(%r4)
|
|
; nextln: ork %r2, %r3, %r2
|
|
; nextln: br %r14
|
|
|
|
function %rotr_i8_imm(i8) -> i8 {
|
|
block0(v0: i8):
|
|
v1 = iconst.i32 3
|
|
v2 = rotl.i8 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: llcr %r2, %r2
|
|
; nextln: sllk %r3, %r2, 3
|
|
; nextln: srlk %r2, %r2, 5
|
|
; nextln: ork %r2, %r3, %r2
|
|
; nextln: br %r14
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; USHR
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
function %ushr_i64_reg(i64, i64) -> i64 {
|
|
block0(v0: i64, v1: i64):
|
|
v2 = ushr.i64 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: srlg %r2, %r2, 0(%r3)
|
|
; nextln: br %r14
|
|
|
|
function %ushr_i64_imm(i64) -> i64 {
|
|
block0(v0: i64):
|
|
v1 = iconst.i32 17
|
|
v2 = ushr.i64 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: srlg %r2, %r2, 17
|
|
; nextln: br %r14
|
|
|
|
function %ushr_i32_reg(i32, i32) -> i32 {
|
|
block0(v0: i32, v1: i32):
|
|
v2 = ushr.i32 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: srlk %r2, %r2, 0(%r3)
|
|
; nextln: br %r14
|
|
|
|
function %ushr_i32_imm(i32) -> i32 {
|
|
block0(v0: i32):
|
|
v1 = iconst.i32 17
|
|
v2 = ushr.i32 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: srlk %r2, %r2, 17
|
|
; nextln: br %r14
|
|
|
|
function %ushr_i16_reg(i16, i16) -> i16 {
|
|
block0(v0: i16, v1: i16):
|
|
v2 = ushr.i16 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: llhr %r2, %r2
|
|
; nextln: nill %r3, 15
|
|
; nextln: srlk %r2, %r2, 0(%r3)
|
|
; nextln: br %r14
|
|
|
|
function %ushr_i16_imm(i16) -> i16 {
|
|
block0(v0: i16):
|
|
v1 = iconst.i32 10
|
|
v2 = ushr.i16 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: llhr %r2, %r2
|
|
; nextln: srlk %r2, %r2, 10
|
|
; nextln: br %r14
|
|
|
|
function %ushr_i8_reg(i8, i8) -> i8 {
|
|
block0(v0: i8, v1: i8):
|
|
v2 = ushr.i8 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: llcr %r2, %r2
|
|
; nextln: nill %r3, 7
|
|
; nextln: srlk %r2, %r2, 0(%r3)
|
|
; nextln: br %r14
|
|
|
|
function %ushr_i8_imm(i8) -> i8 {
|
|
block0(v0: i8):
|
|
v1 = iconst.i32 3
|
|
v2 = ushr.i8 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: llcr %r2, %r2
|
|
; nextln: srlk %r2, %r2, 3
|
|
; nextln: br %r14
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; ISHL
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
function %ishl_i64_reg(i64, i64) -> i64 {
|
|
block0(v0: i64, v1: i64):
|
|
v2 = ishl.i64 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: sllg %r2, %r2, 0(%r3)
|
|
; nextln: br %r14
|
|
|
|
function %ishl_i64_imm(i64) -> i64 {
|
|
block0(v0: i64):
|
|
v1 = iconst.i32 17
|
|
v2 = ishl.i64 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: sllg %r2, %r2, 17
|
|
; nextln: br %r14
|
|
|
|
function %ishl_i32_reg(i32, i32) -> i32 {
|
|
block0(v0: i32, v1: i32):
|
|
v2 = ishl.i32 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: sllk %r2, %r2, 0(%r3)
|
|
; nextln: br %r14
|
|
|
|
function %ishl_i32_imm(i32) -> i32 {
|
|
block0(v0: i32):
|
|
v1 = iconst.i32 17
|
|
v2 = ishl.i32 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: sllk %r2, %r2, 17
|
|
; nextln: br %r14
|
|
|
|
function %ishl_i16_reg(i16, i16) -> i16 {
|
|
block0(v0: i16, v1: i16):
|
|
v2 = ishl.i16 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: nill %r3, 15
|
|
; nextln: sllk %r2, %r2, 0(%r3)
|
|
; nextln: br %r14
|
|
|
|
function %ishl_i16_imm(i16) -> i16 {
|
|
block0(v0: i16):
|
|
v1 = iconst.i32 10
|
|
v2 = ishl.i16 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: sllk %r2, %r2, 10
|
|
; nextln: br %r14
|
|
|
|
function %ishl_i8_reg(i8, i8) -> i8 {
|
|
block0(v0: i8, v1: i8):
|
|
v2 = ishl.i8 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: nill %r3, 7
|
|
; nextln: sllk %r2, %r2, 0(%r3)
|
|
; nextln: br %r14
|
|
|
|
function %ishl_i8_imm(i8) -> i8 {
|
|
block0(v0: i8):
|
|
v1 = iconst.i32 3
|
|
v2 = ishl.i8 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: sllk %r2, %r2, 3
|
|
; nextln: br %r14
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; SSHR
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
function %sshr_i64_reg(i64, i64) -> i64 {
|
|
block0(v0: i64, v1: i64):
|
|
v2 = sshr.i64 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: srag %r2, %r2, 0(%r3)
|
|
; nextln: br %r14
|
|
|
|
function %sshr_i64_imm(i64) -> i64 {
|
|
block0(v0: i64):
|
|
v1 = iconst.i32 17
|
|
v2 = sshr.i64 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: srag %r2, %r2, 17
|
|
; nextln: br %r14
|
|
|
|
function %sshr_i32_reg(i32, i32) -> i32 {
|
|
block0(v0: i32, v1: i32):
|
|
v2 = sshr.i32 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: srak %r2, %r2, 0(%r3)
|
|
; nextln: br %r14
|
|
|
|
function %sshr_i32_imm(i32) -> i32 {
|
|
block0(v0: i32):
|
|
v1 = iconst.i32 17
|
|
v2 = sshr.i32 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: srak %r2, %r2, 17
|
|
; nextln: br %r14
|
|
|
|
function %sshr_i16_reg(i16, i16) -> i16 {
|
|
block0(v0: i16, v1: i16):
|
|
v2 = sshr.i16 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: lhr %r2, %r2
|
|
; nextln: nill %r3, 15
|
|
; nextln: srak %r2, %r2, 0(%r3)
|
|
; nextln: br %r14
|
|
|
|
function %sshr_i16_imm(i16) -> i16 {
|
|
block0(v0: i16):
|
|
v1 = iconst.i32 10
|
|
v2 = sshr.i16 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: lhr %r2, %r2
|
|
; nextln: srak %r2, %r2, 10
|
|
; nextln: br %r14
|
|
|
|
function %sshr_i8_reg(i8, i8) -> i8 {
|
|
block0(v0: i8, v1: i8):
|
|
v2 = sshr.i8 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: lbr %r2, %r2
|
|
; nextln: nill %r3, 7
|
|
; nextln: srak %r2, %r2, 0(%r3)
|
|
; nextln: br %r14
|
|
|
|
function %sshr_i8_imm(i8) -> i8 {
|
|
block0(v0: i8):
|
|
v1 = iconst.i32 3
|
|
v2 = sshr.i8 v0, v1
|
|
return v2
|
|
}
|
|
|
|
; check: lbr %r2, %r2
|
|
; nextln: srak %r2, %r2, 3
|
|
; nextln: br %r14
|
|
|