From 676c6194288e6d8186116e6d68ac2a0f439ddd5f Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Sat, 30 Dec 2023 16:16:33 +0900 Subject: [PATCH] Support reg_addr register class in s390x inline assembly --- compiler/rustc_codegen_gcc/src/asm.rs | 5 +++- compiler/rustc_codegen_llvm/src/asm.rs | 5 +++- compiler/rustc_target/src/asm/s390x.rs | 29 ++++++++++--------- .../asm-experimental-arch.md | 3 +- tests/assembly/asm/s390x-types.rs | 24 +++++++++++++++ 5 files changed, 49 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/asm.rs b/compiler/rustc_codegen_gcc/src/asm.rs index ddd67a994c942..78e8e32b97299 100644 --- a/compiler/rustc_codegen_gcc/src/asm.rs +++ b/compiler/rustc_codegen_gcc/src/asm.rs @@ -634,6 +634,7 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister { } InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => "r", InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg_addr) => "a", InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => "f", InlineAsmRegClass::Err => unreachable!(), } @@ -704,7 +705,9 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => { bug!("LLVM backend does not support SPIR-V") }, - InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg) => cx.type_i32(), + InlineAsmRegClass::S390x( + S390xInlineAsmRegClass::reg | S390xInlineAsmRegClass::reg_addr + ) => cx.type_i32(), InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => cx.type_f64(), InlineAsmRegClass::Err => unreachable!(), } diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index 1323261ae9240..a413466093bed 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -690,6 +690,7 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) -> InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_iw) => "w", InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_ptr) => "e", InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg_addr) => "a", InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => "f", InlineAsmRegClass::Msp430(Msp430InlineAsmRegClass::reg) => "r", InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => "r", @@ -867,7 +868,9 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &' InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_pair) => cx.type_i16(), InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_iw) => cx.type_i16(), InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_ptr) => cx.type_i16(), - InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg) => cx.type_i32(), + InlineAsmRegClass::S390x( + S390xInlineAsmRegClass::reg | S390xInlineAsmRegClass::reg_addr, + ) => cx.type_i32(), InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => cx.type_f64(), InlineAsmRegClass::Msp430(Msp430InlineAsmRegClass::reg) => cx.type_i16(), InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => cx.type_i32(), diff --git a/compiler/rustc_target/src/asm/s390x.rs b/compiler/rustc_target/src/asm/s390x.rs index 0a50064f58755..b8afeb824d847 100644 --- a/compiler/rustc_target/src/asm/s390x.rs +++ b/compiler/rustc_target/src/asm/s390x.rs @@ -6,6 +6,7 @@ use std::fmt; def_reg_class! { S390x S390xInlineAsmRegClass { reg, + reg_addr, freg, } } @@ -36,7 +37,7 @@ impl S390xInlineAsmRegClass { arch: InlineAsmArch, ) -> &'static [(InlineAsmType, Option)] { match (self, arch) { - (Self::reg, _) => types! { _: I8, I16, I32, I64; }, + (Self::reg | Self::reg_addr, _) => types! { _: I8, I16, I32, I64; }, (Self::freg, _) => types! { _: F32, F64; }, } } @@ -45,19 +46,19 @@ impl S390xInlineAsmRegClass { def_regs! { S390x S390xInlineAsmReg S390xInlineAsmRegClass { r0: reg = ["r0"], - r1: reg = ["r1"], - r2: reg = ["r2"], - r3: reg = ["r3"], - r4: reg = ["r4"], - r5: reg = ["r5"], - r6: reg = ["r6"], - r7: reg = ["r7"], - r8: reg = ["r8"], - r9: reg = ["r9"], - r10: reg = ["r10"], - r12: reg = ["r12"], - r13: reg = ["r13"], - r14: reg = ["r14"], + r1: reg, reg_addr = ["r1"], + r2: reg, reg_addr = ["r2"], + r3: reg, reg_addr = ["r3"], + r4: reg, reg_addr = ["r4"], + r5: reg, reg_addr = ["r5"], + r6: reg, reg_addr = ["r6"], + r7: reg, reg_addr = ["r7"], + r8: reg, reg_addr = ["r8"], + r9: reg, reg_addr = ["r9"], + r10: reg, reg_addr = ["r10"], + r12: reg, reg_addr = ["r12"], + r13: reg, reg_addr = ["r13"], + r14: reg, reg_addr = ["r14"], f0: freg = ["f0"], f1: freg = ["f1"], f2: freg = ["f2"], diff --git a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md index 968c9bb4ebb86..4e6ae1c7cc14e 100644 --- a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md +++ b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md @@ -84,7 +84,7 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | M68k | `reg_data` | None | `i8`, `i16`, `i32` | | CSKY | `reg` | None | `i8`, `i16`, `i32` | | CSKY | `freg` | None | `f32`, | -| s390x | `reg` | None | `i8`, `i16`, `i32`, `i64` | +| s390x | `reg`, `reg_addr` | None | `i8`, `i16`, `i32`, `i64` | | s390x | `freg` | None | `f32`, `f64` | ## Register aliases @@ -161,6 +161,7 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | PowerPC | `reg_nonzero` | None | `3` | `b` | | PowerPC | `freg` | None | `0` | None | | s390x | `reg` | None | `%r0` | None | +| s390x | `reg_addr` | None | `%r1` | `a` | | s390x | `freg` | None | `%f0` | None | | CSKY | `reg` | None | `r0` | None | | CSKY | `freg` | None | `f0` | None | diff --git a/tests/assembly/asm/s390x-types.rs b/tests/assembly/asm/s390x-types.rs index 2fb404dd9b280..c39a82c3b1c48 100644 --- a/tests/assembly/asm/s390x-types.rs +++ b/tests/assembly/asm/s390x-types.rs @@ -112,6 +112,30 @@ check!(reg_i32, i32, reg, "lgr"); // CHECK: #NO_APP check!(reg_i64, i64, reg, "lgr"); +// CHECK-LABEL: reg_i8_addr: +// CHECK: #APP +// CHECK: lgr %r{{[0-9]+}}, %r{{[0-9]+}} +// CHECK: #NO_APP +check!(reg_i8_addr, i8, reg_addr, "lgr"); + +// CHECK-LABEL: reg_i16_addr: +// CHECK: #APP +// CHECK: lgr %r{{[0-9]+}}, %r{{[0-9]+}} +// CHECK: #NO_APP +check!(reg_i16_addr, i16, reg_addr, "lgr"); + +// CHECK-LABEL: reg_i32_addr: +// CHECK: #APP +// CHECK: lgr %r{{[0-9]+}}, %r{{[0-9]+}} +// CHECK: #NO_APP +check!(reg_i32_addr, i32, reg_addr, "lgr"); + +// CHECK-LABEL: reg_i64_addr: +// CHECK: #APP +// CHECK: lgr %r{{[0-9]+}}, %r{{[0-9]+}} +// CHECK: #NO_APP +check!(reg_i64_addr, i64, reg_addr, "lgr"); + // CHECK-LABEL: reg_f32: // CHECK: #APP // CHECK: ler %f{{[0-9]+}}, %f{{[0-9]+}}