s390x: Refactor branch and jumptable emission

The BranchTarget abstraction is no longer needed, since all branches are
being emitted using a MachLabel target.  Remove BranchTarget and simply
use MachLabel everywhere a branch target is required.  (This brings the
s390x back-end in line with what x64 does as well.)

In addition, simplify jumptable emission by moving all instructions
that do not depend on the internal label (i.e. the conditional branch
to the default label, as well as the scaling the index register) out of
the combined JTSequence instruction.

This refactoring will make moving branch generation to ISLE easier.
This commit is contained in:
Ulrich Weigand
2022-01-24 12:03:59 +01:00
parent 881c19473d
commit cee00c6591
10 changed files with 731 additions and 870 deletions

View File

@@ -1567,11 +1567,11 @@ fn test_s390x_binemit() {
op: CmpOp::CmpS32,
rn: gpr(1),
mem: MemArg::Label {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(1),
},
},
"C61D00000020",
"crl %r1, 64",
"C61D00000003",
"crl %r1, label1",
));
insns.push((
Inst::CmpRX {
@@ -1606,11 +1606,11 @@ fn test_s390x_binemit() {
op: CmpOp::CmpS32Ext16,
rn: gpr(1),
mem: MemArg::Label {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(1),
},
},
"C61500000020",
"chrl %r1, 64",
"C61500000003",
"chrl %r1, label1",
));
insns.push((
Inst::CmpRX {
@@ -1631,11 +1631,11 @@ fn test_s390x_binemit() {
op: CmpOp::CmpS64,
rn: gpr(1),
mem: MemArg::Label {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(1),
},
},
"C61800000020",
"cgrl %r1, 64",
"C61800000003",
"cgrl %r1, label1",
));
insns.push((
Inst::CmpRX {
@@ -1656,11 +1656,11 @@ fn test_s390x_binemit() {
op: CmpOp::CmpS64Ext16,
rn: gpr(1),
mem: MemArg::Label {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(1),
},
},
"C61400000020",
"cghrl %r1, 64",
"C61400000003",
"cghrl %r1, label1",
));
insns.push((
Inst::CmpRX {
@@ -1681,11 +1681,11 @@ fn test_s390x_binemit() {
op: CmpOp::CmpS64Ext32,
rn: gpr(1),
mem: MemArg::Label {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(1),
},
},
"C61C00000020",
"cgfrl %r1, 64",
"C61C00000003",
"cgfrl %r1, label1",
));
insns.push((
Inst::CmpRX {
@@ -1720,22 +1720,22 @@ fn test_s390x_binemit() {
op: CmpOp::CmpL32,
rn: gpr(1),
mem: MemArg::Label {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(1),
},
},
"C61F00000020",
"clrl %r1, 64",
"C61F00000003",
"clrl %r1, label1",
));
insns.push((
Inst::CmpRX {
op: CmpOp::CmpL32Ext16,
rn: gpr(1),
mem: MemArg::Label {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(1),
},
},
"C61700000020",
"clhrl %r1, 64",
"C61700000003",
"clhrl %r1, label1",
));
insns.push((
Inst::CmpRX {
@@ -1756,22 +1756,22 @@ fn test_s390x_binemit() {
op: CmpOp::CmpL64,
rn: gpr(1),
mem: MemArg::Label {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(1),
},
},
"C61A00000020",
"clgrl %r1, 64",
"C61A00000003",
"clgrl %r1, label1",
));
insns.push((
Inst::CmpRX {
op: CmpOp::CmpL64Ext16,
rn: gpr(1),
mem: MemArg::Label {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(1),
},
},
"C61600000020",
"clghrl %r1, 64",
"C61600000003",
"clghrl %r1, label1",
));
insns.push((
Inst::CmpRX {
@@ -1792,11 +1792,11 @@ fn test_s390x_binemit() {
op: CmpOp::CmpL64Ext32,
rn: gpr(1),
mem: MemArg::Label {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(1),
},
},
"C61E00000020",
"clgfrl %r1, 64",
"C61E00000003",
"clgfrl %r1, label1",
));
insns.push((
@@ -4433,81 +4433,81 @@ fn test_s390x_binemit() {
Inst::Load32 {
rd: writable_gpr(1),
mem: MemArg::Label {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(1),
},
},
"C41D00000020",
"lrl %r1, 64",
"C41D00000003",
"lrl %r1, label1",
));
insns.push((
Inst::Load32SExt16 {
rd: writable_gpr(1),
mem: MemArg::Label {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(1),
},
},
"C41500000020",
"lhrl %r1, 64",
"C41500000003",
"lhrl %r1, label1",
));
insns.push((
Inst::Load32ZExt16 {
rd: writable_gpr(1),
mem: MemArg::Label {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(1),
},
},
"C41200000020",
"llhrl %r1, 64",
"C41200000003",
"llhrl %r1, label1",
));
insns.push((
Inst::Load64 {
rd: writable_gpr(1),
mem: MemArg::Label {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(1),
},
},
"C41800000020",
"lgrl %r1, 64",
"C41800000003",
"lgrl %r1, label1",
));
insns.push((
Inst::Load64SExt16 {
rd: writable_gpr(1),
mem: MemArg::Label {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(1),
},
},
"C41400000020",
"lghrl %r1, 64",
"C41400000003",
"lghrl %r1, label1",
));
insns.push((
Inst::Load64ZExt16 {
rd: writable_gpr(1),
mem: MemArg::Label {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(1),
},
},
"C41600000020",
"llghrl %r1, 64",
"C41600000003",
"llghrl %r1, label1",
));
insns.push((
Inst::Load64SExt32 {
rd: writable_gpr(1),
mem: MemArg::Label {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(1),
},
},
"C41C00000020",
"lgfrl %r1, 64",
"C41C00000003",
"lgfrl %r1, label1",
));
insns.push((
Inst::Load64ZExt32 {
rd: writable_gpr(1),
mem: MemArg::Label {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(1),
},
},
"C41E00000020",
"llgfrl %r1, 64",
"C41E00000003",
"llgfrl %r1, label1",
));
insns.push((
Inst::LoadRev16 {
@@ -5687,31 +5687,31 @@ fn test_s390x_binemit() {
Inst::Store16 {
rd: gpr(1),
mem: MemArg::Label {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(1),
},
},
"C41700000020",
"sthrl %r1, 64",
"C41700000003",
"sthrl %r1, label1",
));
insns.push((
Inst::Store32 {
rd: gpr(1),
mem: MemArg::Label {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(1),
},
},
"C41F00000020",
"strl %r1, 64",
"C41F00000003",
"strl %r1, label1",
));
insns.push((
Inst::Store64 {
rd: gpr(1),
mem: MemArg::Label {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(1),
},
},
"C41B00000020",
"stgrl %r1, 64",
"C41B00000003",
"stgrl %r1, label1",
));
insns.push((
@@ -5932,11 +5932,11 @@ fn test_s390x_binemit() {
Inst::LoadAddr {
rd: writable_gpr(1),
mem: MemArg::Label {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(1),
},
},
"C01000000020",
"larl %r1, 64",
"C01000000003",
"larl %r1, label1",
));
insns.push((
Inst::LoadAddr {
@@ -6396,250 +6396,250 @@ fn test_s390x_binemit() {
insns.push((
Inst::Jump {
dest: BranchTarget::ResolvedOffset(64),
dest: MachLabel::from_block(0),
},
"C0F400000020",
"jg 64",
"C0F400000000",
"jg label0",
));
insns.push((
Inst::OneWayCondBr {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(0),
cond: Cond::from_mask(1),
},
"C01400000020",
"jgo 64",
"C01400000000",
"jgo label0",
));
insns.push((
Inst::OneWayCondBr {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(0),
cond: Cond::from_mask(2),
},
"C02400000020",
"jgh 64",
"C02400000000",
"jgh label0",
));
insns.push((
Inst::OneWayCondBr {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(0),
cond: Cond::from_mask(3),
},
"C03400000020",
"jgnle 64",
"C03400000000",
"jgnle label0",
));
insns.push((
Inst::OneWayCondBr {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(0),
cond: Cond::from_mask(4),
},
"C04400000020",
"jgl 64",
"C04400000000",
"jgl label0",
));
insns.push((
Inst::OneWayCondBr {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(0),
cond: Cond::from_mask(5),
},
"C05400000020",
"jgnhe 64",
"C05400000000",
"jgnhe label0",
));
insns.push((
Inst::OneWayCondBr {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(0),
cond: Cond::from_mask(6),
},
"C06400000020",
"jglh 64",
"C06400000000",
"jglh label0",
));
insns.push((
Inst::OneWayCondBr {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(0),
cond: Cond::from_mask(7),
},
"C07400000020",
"jgne 64",
"C07400000000",
"jgne label0",
));
insns.push((
Inst::OneWayCondBr {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(0),
cond: Cond::from_mask(8),
},
"C08400000020",
"jge 64",
"C08400000000",
"jge label0",
));
insns.push((
Inst::OneWayCondBr {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(0),
cond: Cond::from_mask(9),
},
"C09400000020",
"jgnlh 64",
"C09400000000",
"jgnlh label0",
));
insns.push((
Inst::OneWayCondBr {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(0),
cond: Cond::from_mask(10),
},
"C0A400000020",
"jghe 64",
"C0A400000000",
"jghe label0",
));
insns.push((
Inst::OneWayCondBr {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(0),
cond: Cond::from_mask(11),
},
"C0B400000020",
"jgnl 64",
"C0B400000000",
"jgnl label0",
));
insns.push((
Inst::OneWayCondBr {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(0),
cond: Cond::from_mask(12),
},
"C0C400000020",
"jgle 64",
"C0C400000000",
"jgle label0",
));
insns.push((
Inst::OneWayCondBr {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(0),
cond: Cond::from_mask(13),
},
"C0D400000020",
"jgnh 64",
"C0D400000000",
"jgnh label0",
));
insns.push((
Inst::OneWayCondBr {
target: BranchTarget::ResolvedOffset(64),
target: MachLabel::from_block(0),
cond: Cond::from_mask(14),
},
"C0E400000020",
"jgno 64",
"C0E400000000",
"jgno label0",
));
insns.push((
Inst::CondBr {
taken: BranchTarget::ResolvedOffset(64),
not_taken: BranchTarget::ResolvedOffset(128),
taken: MachLabel::from_block(0),
not_taken: MachLabel::from_block(0),
cond: Cond::from_mask(1),
},
"C01400000020C0F400000040",
"jgo 64 ; jg 128",
"C01400000000C0F4FFFFFFFD",
"jgo label0 ; jg label0",
));
insns.push((
Inst::CondBr {
taken: BranchTarget::ResolvedOffset(64),
not_taken: BranchTarget::ResolvedOffset(128),
taken: MachLabel::from_block(0),
not_taken: MachLabel::from_block(0),
cond: Cond::from_mask(2),
},
"C02400000020C0F400000040",
"jgh 64 ; jg 128",
"C02400000000C0F4FFFFFFFD",
"jgh label0 ; jg label0",
));
insns.push((
Inst::CondBr {
taken: BranchTarget::ResolvedOffset(64),
not_taken: BranchTarget::ResolvedOffset(128),
taken: MachLabel::from_block(0),
not_taken: MachLabel::from_block(0),
cond: Cond::from_mask(3),
},
"C03400000020C0F400000040",
"jgnle 64 ; jg 128",
"C03400000000C0F4FFFFFFFD",
"jgnle label0 ; jg label0",
));
insns.push((
Inst::CondBr {
taken: BranchTarget::ResolvedOffset(64),
not_taken: BranchTarget::ResolvedOffset(128),
taken: MachLabel::from_block(0),
not_taken: MachLabel::from_block(0),
cond: Cond::from_mask(4),
},
"C04400000020C0F400000040",
"jgl 64 ; jg 128",
"C04400000000C0F4FFFFFFFD",
"jgl label0 ; jg label0",
));
insns.push((
Inst::CondBr {
taken: BranchTarget::ResolvedOffset(64),
not_taken: BranchTarget::ResolvedOffset(128),
taken: MachLabel::from_block(0),
not_taken: MachLabel::from_block(0),
cond: Cond::from_mask(5),
},
"C05400000020C0F400000040",
"jgnhe 64 ; jg 128",
"C05400000000C0F4FFFFFFFD",
"jgnhe label0 ; jg label0",
));
insns.push((
Inst::CondBr {
taken: BranchTarget::ResolvedOffset(64),
not_taken: BranchTarget::ResolvedOffset(128),
taken: MachLabel::from_block(0),
not_taken: MachLabel::from_block(0),
cond: Cond::from_mask(6),
},
"C06400000020C0F400000040",
"jglh 64 ; jg 128",
"C06400000000C0F4FFFFFFFD",
"jglh label0 ; jg label0",
));
insns.push((
Inst::CondBr {
taken: BranchTarget::ResolvedOffset(64),
not_taken: BranchTarget::ResolvedOffset(128),
taken: MachLabel::from_block(0),
not_taken: MachLabel::from_block(0),
cond: Cond::from_mask(7),
},
"C07400000020C0F400000040",
"jgne 64 ; jg 128",
"C07400000000C0F4FFFFFFFD",
"jgne label0 ; jg label0",
));
insns.push((
Inst::CondBr {
taken: BranchTarget::ResolvedOffset(64),
not_taken: BranchTarget::ResolvedOffset(128),
taken: MachLabel::from_block(0),
not_taken: MachLabel::from_block(0),
cond: Cond::from_mask(8),
},
"C08400000020C0F400000040",
"jge 64 ; jg 128",
"C08400000000C0F4FFFFFFFD",
"jge label0 ; jg label0",
));
insns.push((
Inst::CondBr {
taken: BranchTarget::ResolvedOffset(64),
not_taken: BranchTarget::ResolvedOffset(128),
taken: MachLabel::from_block(0),
not_taken: MachLabel::from_block(0),
cond: Cond::from_mask(9),
},
"C09400000020C0F400000040",
"jgnlh 64 ; jg 128",
"C09400000000C0F4FFFFFFFD",
"jgnlh label0 ; jg label0",
));
insns.push((
Inst::CondBr {
taken: BranchTarget::ResolvedOffset(64),
not_taken: BranchTarget::ResolvedOffset(128),
taken: MachLabel::from_block(0),
not_taken: MachLabel::from_block(0),
cond: Cond::from_mask(10),
},
"C0A400000020C0F400000040",
"jghe 64 ; jg 128",
"C0A400000000C0F4FFFFFFFD",
"jghe label0 ; jg label0",
));
insns.push((
Inst::CondBr {
taken: BranchTarget::ResolvedOffset(64),
not_taken: BranchTarget::ResolvedOffset(128),
taken: MachLabel::from_block(0),
not_taken: MachLabel::from_block(0),
cond: Cond::from_mask(11),
},
"C0B400000020C0F400000040",
"jgnl 64 ; jg 128",
"C0B400000000C0F4FFFFFFFD",
"jgnl label0 ; jg label0",
));
insns.push((
Inst::CondBr {
taken: BranchTarget::ResolvedOffset(64),
not_taken: BranchTarget::ResolvedOffset(128),
taken: MachLabel::from_block(0),
not_taken: MachLabel::from_block(0),
cond: Cond::from_mask(12),
},
"C0C400000020C0F400000040",
"jgle 64 ; jg 128",
"C0C400000000C0F4FFFFFFFD",
"jgle label0 ; jg label0",
));
insns.push((
Inst::CondBr {
taken: BranchTarget::ResolvedOffset(64),
not_taken: BranchTarget::ResolvedOffset(128),
taken: MachLabel::from_block(0),
not_taken: MachLabel::from_block(0),
cond: Cond::from_mask(13),
},
"C0D400000020C0F400000040",
"jgnh 64 ; jg 128",
"C0D400000000C0F4FFFFFFFD",
"jgnh label0 ; jg label0",
));
insns.push((
Inst::CondBr {
taken: BranchTarget::ResolvedOffset(64),
not_taken: BranchTarget::ResolvedOffset(128),
taken: MachLabel::from_block(0),
not_taken: MachLabel::from_block(0),
cond: Cond::from_mask(14),
},
"C0E400000020C0F400000040",
"jgno 64 ; jg 128",
"C0E400000000C0F4FFFFFFFD",
"jgno label0 ; jg label0",
));
insns.push((
@@ -8128,7 +8128,18 @@ fn test_s390x_binemit() {
assert_eq!(expected_printing, actual_printing);
let mut buffer = MachBuffer::new();
// Label 0 before the instruction.
let label0 = buffer.get_label();
buffer.bind_label(label0);
// Emit the instruction.
insn.emit(&mut buffer, &emit_info, &mut Default::default());
// Label 1 after the instruction.
let label1 = buffer.get_label();
buffer.bind_label(label1);
let buffer = buffer.finish();
let actual_encoding = &buffer.stringify_code_bytes();
assert_eq!(expected_encoding, actual_encoding);