From: Andreas Arnez Date: Tue, 14 Feb 2023 14:35:48 +0000 (+0100) Subject: Bug 465782 - s390x: Adjust inline assemblies for Clang X-Git-Tag: VALGRIND_3_22_0~155 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=165c3769580b7f256aedb0b5d48972fa28b30094;p=thirdparty%2Fvalgrind.git Bug 465782 - s390x: Adjust inline assemblies for Clang Some s390x inline assemblies are written in such a way that they are understood by GCC but not by Clang: * use of "f" constraint for unsigned long variable * use of "b" modifier when passing a constant * use of the register notation "r11" in ".cfi_def_cfa" Adjust the affected inline assemblies to avoid these constructs. --- diff --git a/VEX/priv/guest_s390_helpers.c b/VEX/priv/guest_s390_helpers.c index 804b92a296..95bb653274 100644 --- a/VEX/priv/guest_s390_helpers.c +++ b/VEX/priv/guest_s390_helpers.c @@ -913,7 +913,7 @@ s390_do_cvb(ULong decimal) __asm__ volatile ( "cvb %[result],%[input]\n\t" : [result] "=d"(binary) - : [input] "m"(decimal) + : [input] "R"(decimal) ); return binary; @@ -1000,8 +1000,12 @@ UInt s390_do_pfpo(UInt gpr0) { return 0; } /*--- Helper for condition code. ---*/ /*------------------------------------------------------------*/ -/* Convert an IRRoundingMode value to s390_bfp_round_t */ #if defined(VGA_s390x) +typedef long double Float128; +union s390x_F64 { ULong i; Double f; }; +union s390x_F128 { struct { ULong hi, lo; } i; Float128 f; }; + +/* Convert an IRRoundingMode value to s390_bfp_round_t */ static s390_bfp_round_t decode_bfp_rounding_mode(UInt irrm) { @@ -1013,8 +1017,6 @@ decode_bfp_rounding_mode(UInt irrm) } vpanic("decode_bfp_rounding_mode"); } -#endif - #define S390_CC_FOR_BINARY(opcode,cc_dep1,cc_dep2) \ ({ \ @@ -1041,13 +1043,14 @@ decode_bfp_rounding_mode(UInt irrm) /* Recover the original DEP2 value. See comment near s390_cc_thunk_put3 \ for rationale. */ \ cc_dep2 = cc_dep2 ^ cc_ndep; \ + ULong tmp = 1; \ __asm__ volatile ( \ - "lghi 0,1\n\t" \ - "sr 0,%[op3]\n\t" /* borrow to cc */ \ + "sr %[tmp],%[op3]\n\t" /* borrow to cc */ \ opcode " %[op1],%[op2]\n\t" /* then redo the op */\ - "ipm %[psw]\n\t" : [psw] "=d"(psw), [op1] "+&d"(cc_dep1) \ + "ipm %[psw]\n\t" : [psw] "=d"(psw), [op1] "+&d"(cc_dep1), \ + [tmp] "+&d"(tmp) \ : [op2] "d"(cc_dep2), [op3] "d"(cc_ndep) \ - : "0", "cc");\ + : "cc");\ psw >> 28; /* cc */ \ }) @@ -1056,46 +1059,52 @@ decode_bfp_rounding_mode(UInt irrm) /* Recover the original DEP2 value. See comment near s390_cc_thunk_put3 \ for rationale. */ \ cc_dep2 = cc_dep2 ^ cc_ndep; \ + ULong tmp; \ __asm__ volatile ( \ - "lgfr 0,%[op3]\n\t" /* first load cc_ndep */ \ - "aghi 0,0\n\t" /* and convert it into a cc */ \ + "lgfr %[tmp],%[op3]\n\t" /* first load cc_ndep */ \ + "aghi %[tmp],0\n\t" /* and convert it into a cc */ \ opcode " %[op1],%[op2]\n\t" /* then redo the op */\ - "ipm %[psw]\n\t" : [psw] "=d"(psw), [op1] "+&d"(cc_dep1) \ + "ipm %[psw]\n\t" : [psw] "=d"(psw), [op1] "+&d"(cc_dep1), \ + [tmp] "=&d"(tmp) \ : [op2] "d"(cc_dep2), [op3] "d"(cc_ndep) \ - : "0", "cc");\ + : "cc");\ psw >> 28; /* cc */ \ }) #define S390_CC_FOR_BFP_RESULT(opcode,cc_dep1) \ ({ \ + union s390x_F64 op = { .i = cc_dep1 }; \ + Double tmp; \ __asm__ volatile ( \ - opcode " 0,%[op]\n\t" \ - "ipm %[psw]\n\t" : [psw] "=d"(psw) \ - : [op] "f"(cc_dep1) \ - : "cc", "f0");\ + opcode " %[tmp],%[op]\n\t" \ + "ipm %[psw]\n\t" : [psw] "=d"(psw), [tmp] "=f"(tmp) \ + : [op] "f"(op.f) \ + : "cc");\ psw >> 28; /* cc */ \ }) #define S390_CC_FOR_BFP128_RESULT(hi,lo) \ ({ \ + union s390x_F128 op = { .i = { hi, lo } }; \ + Float128 tmp; \ __asm__ volatile ( \ - "ldr 4,%[high]\n\t" \ - "ldr 6,%[low]\n\t" \ - "ltxbr 0,4\n\t" \ - "ipm %[psw]\n\t" : [psw] "=d"(psw) \ - : [high] "f"(hi), [low] "f"(lo) \ - : "cc", "f0", "f2", "f4", "f6");\ + "ltxbr %[tmp],%[op]\n\t" \ + "ipm %[psw]\n\t" : [psw] "=d"(psw), [tmp] "=f"(tmp) \ + : [op] "f"(op.f) \ + : "cc");\ psw >> 28; /* cc */ \ }) #define S390_CC_FOR_BFP_CONVERT_AUX(opcode,cc_dep1,rounding_mode) \ ({ \ + union s390x_F64 op = { .i = cc_dep1 }; \ + ULong tmp; \ __asm__ volatile ( \ - opcode " 0," #rounding_mode ",%[op]\n\t" \ - "ipm %[psw]\n\t" : [psw] "=d"(psw) \ - : [op] "f"(cc_dep1) \ - : "cc", "r0");\ + opcode " %[tmp]," #rounding_mode ",%[op]\n\t" \ + "ipm %[psw]\n\t" : [psw] "=d"(psw), [tmp] "=d"(tmp) \ + : [op] "f"(op.f) \ + : "cc");\ psw >> 28; /* cc */ \ }) @@ -1123,11 +1132,13 @@ decode_bfp_rounding_mode(UInt irrm) #define S390_CC_FOR_BFP_UCONVERT_AUX(opcode,cc_dep1,rounding_mode) \ ({ \ + union s390x_F64 op = { .i = cc_dep1 }; \ + ULong tmp; \ __asm__ volatile ( \ - opcode ",0,%[op]," #rounding_mode ",0\n\t" \ - "ipm %[psw]\n\t" : [psw] "=d"(psw) \ - : [op] "f"(cc_dep1) \ - : "cc", "r0");\ + opcode ",%[tmp],%[op]," #rounding_mode ",0\n\t" \ + "ipm %[psw]\n\t" : [psw] "=d"(psw), [tmp] "=d"(tmp) \ + : [op] "f"(op.f) \ + : "cc");\ psw >> 28; /* cc */ \ }) @@ -1155,13 +1166,13 @@ decode_bfp_rounding_mode(UInt irrm) #define S390_CC_FOR_BFP128_CONVERT_AUX(opcode,hi,lo,rounding_mode) \ ({ \ + union s390x_F128 op = { .i = { hi, lo } }; \ + ULong tmp; \ __asm__ volatile ( \ - "ldr 4,%[high]\n\t" \ - "ldr 6,%[low]\n\t" \ - opcode " 0," #rounding_mode ",4\n\t" \ - "ipm %[psw]\n\t" : [psw] "=d"(psw) \ - : [high] "f"(hi), [low] "f"(lo) \ - : "cc", "r0", "f4", "f6");\ + opcode " %[tmp]," #rounding_mode ",%[op]\n\t" \ + "ipm %[psw]\n\t" : [psw] "=d"(psw), [tmp] "=d"(tmp) \ + : [op] "f"(op.f) \ + : "cc");\ psw >> 28; /* cc */ \ }) @@ -1192,13 +1203,13 @@ decode_bfp_rounding_mode(UInt irrm) #define S390_CC_FOR_BFP128_UCONVERT_AUX(opcode,hi,lo,rounding_mode) \ ({ \ + union s390x_F128 op = { .i = { hi, lo } }; \ + ULong tmp; \ __asm__ volatile ( \ - "ldr 4,%[high]\n\t" \ - "ldr 6,%[low]\n\t" \ - opcode ",0,4," #rounding_mode ",0\n\t" \ - "ipm %[psw]\n\t" : [psw] "=d"(psw) \ - : [high] "f"(hi), [low] "f"(lo) \ - : "cc", "r0", "f4", "f6");\ + opcode ",%[tmp],%[op]," #rounding_mode ",0\n\t" \ + "ipm %[psw]\n\t" : [psw] "=d"(psw), [tmp] "=d"(tmp) \ + : [op] "f"(op.f) \ + : "cc");\ psw >> 28; /* cc */ \ }) @@ -1229,10 +1240,11 @@ decode_bfp_rounding_mode(UInt irrm) #define S390_CC_FOR_BFP_TDC(opcode,cc_dep1,cc_dep2) \ ({ \ + union s390x_F64 val = { .i = cc_dep1 }; \ __asm__ volatile ( \ opcode " %[value],0(%[class])\n\t" \ "ipm %[psw]\n\t" : [psw] "=d"(psw) \ - : [value] "f"(cc_dep1), \ + : [value] "f"(val.f), \ [class] "a"(cc_dep2) \ : "cc");\ psw >> 28; /* cc */ \ @@ -1243,19 +1255,16 @@ decode_bfp_rounding_mode(UInt irrm) /* Recover the original DEP2 value. See comment near \ s390_cc_thunk_put1f128Z for rationale. */ \ cc_dep2 = cc_dep2 ^ cc_ndep; \ + union s390x_F128 val = { .i = { cc_dep1, cc_dep2 } }; \ __asm__ volatile ( \ - "ldr 4,%[high]\n\t" \ - "ldr 6,%[low]\n\t" \ - "tcxb 4,0(%[class])\n\t" \ + "tcxb %[value],0(%[class])\n\t" \ "ipm %[psw]\n\t" : [psw] "=d"(psw) \ - : [high] "f"(cc_dep1), [low] "f"(cc_dep2), \ - [class] "a"(cc_ndep) \ - : "cc", "f4", "f6");\ + : [value] "f"(val.f), [class] "a"(cc_ndep) \ + : "cc");\ psw >> 28; /* cc */ \ }) /* Convert an IRRoundingMode value to s390_dfp_round_t */ -#if defined(VGA_s390x) static s390_dfp_round_t decode_dfp_rounding_mode(UInt irrm) { @@ -1279,36 +1288,38 @@ decode_dfp_rounding_mode(UInt irrm) } vpanic("decode_dfp_rounding_mode"); } -#endif #define S390_CC_FOR_DFP_RESULT(cc_dep1) \ ({ \ + union s390x_F64 op = { .i = cc_dep1 }; \ + Double tmp; \ __asm__ volatile ( \ - ".insn rre, 0xb3d60000,0,%[op]\n\t" /* LTDTR */ \ - "ipm %[psw]\n\t" : [psw] "=d"(psw) \ - : [op] "f"(cc_dep1) \ - : "cc", "f0"); \ + ".insn rre, 0xb3d60000,%[tmp],%[op]\n\t" /* LTDTR */ \ + "ipm %[psw]\n\t" : [psw] "=d"(psw), [tmp] "=f"(tmp) \ + : [op] "f"(op.f) \ + : "cc");\ psw >> 28; /* cc */ \ }) #define S390_CC_FOR_DFP128_RESULT(hi,lo) \ ({ \ + union s390x_F128 op = { .i = { hi, lo } }; \ + Float128 tmp; \ __asm__ volatile ( \ - "ldr 4,%[high]\n\t" \ - "ldr 6,%[low]\n\t" \ - ".insn rre, 0xb3de0000,0,4\n\t" /* LTXTR */ \ - "ipm %[psw]\n\t" : [psw] "=d"(psw) \ - : [high] "f"(hi), [low] "f"(lo) \ - : "cc", "f0", "f2", "f4", "f6"); \ + ".insn rre, 0xb3de0000,%[tmp],%[op]\n\t" /* LTXTR */ \ + "ipm %[psw]\n\t" : [psw] "=d"(psw), [tmp] "=f"(tmp) \ + : [op] "f"(op.f) \ + : "cc"); \ psw >> 28; /* cc */ \ }) #define S390_CC_FOR_DFP_TD(opcode,cc_dep1,cc_dep2) \ ({ \ + union s390x_F64 val = { .i = cc_dep1 }; \ __asm__ volatile ( \ opcode ",%[value],0(%[class])\n\t" \ "ipm %[psw]\n\t" : [psw] "=d"(psw) \ - : [value] "f"(cc_dep1), \ + : [value] "f"(val.f), \ [class] "a"(cc_dep2) \ : "cc"); \ psw >> 28; /* cc */ \ @@ -1319,24 +1330,25 @@ decode_dfp_rounding_mode(UInt irrm) /* Recover the original DEP2 value. See comment near \ s390_cc_thunk_put1d128Z for rationale. */ \ cc_dep2 = cc_dep2 ^ cc_ndep; \ + union s390x_F128 val = { .i = { cc_dep1, cc_dep2 } }; \ __asm__ volatile ( \ - "ldr 4,%[high]\n\t" \ - "ldr 6,%[low]\n\t" \ - opcode ",4,0(%[class])\n\t" \ + opcode ",%[value],0(%[class])\n\t" \ "ipm %[psw]\n\t" : [psw] "=d"(psw) \ - : [high] "f"(cc_dep1), [low] "f"(cc_dep2), \ + : [value] "f"(val.f), \ [class] "a"(cc_ndep) \ - : "cc", "f4", "f6"); \ + : "cc"); \ psw >> 28; /* cc */ \ }) #define S390_CC_FOR_DFP_CONVERT_AUX(opcode,cc_dep1,rounding_mode) \ ({ \ + union s390x_F64 op = { .i = cc_dep1 }; \ + Double tmp; \ __asm__ volatile ( \ - opcode ",0,%[op]," #rounding_mode ",0\n\t" \ - "ipm %[psw]\n\t" : [psw] "=d"(psw) \ - : [op] "f"(cc_dep1) \ - : "cc", "r0"); \ + opcode ",%[tmp],%[op]," #rounding_mode ",0\n\t" \ + "ipm %[psw]\n\t" : [psw] "=d"(psw), [tmp] "=f"(tmp) \ + : [op] "f"(op.f) \ + : "cc"); \ psw >> 28; /* cc */ \ }) @@ -1382,11 +1394,13 @@ decode_dfp_rounding_mode(UInt irrm) #define S390_CC_FOR_DFP_UCONVERT_AUX(opcode,cc_dep1,rounding_mode) \ ({ \ + union s390x_F64 op = { .i = cc_dep1 }; \ + Double tmp; \ __asm__ volatile ( \ - opcode ",0,%[op]," #rounding_mode ",0\n\t" \ - "ipm %[psw]\n\t" : [psw] "=d"(psw) \ - : [op] "f"(cc_dep1) \ - : "cc", "r0"); \ + opcode ",%[tmp],%[op]," #rounding_mode ",0\n\t" \ + "ipm %[psw]\n\t" : [psw] "=d"(psw), [tmp] "=f"(tmp) \ + : [op] "f"(op.f) \ + : "cc"); \ psw >> 28; /* cc */ \ }) @@ -1432,13 +1446,13 @@ decode_dfp_rounding_mode(UInt irrm) #define S390_CC_FOR_DFP128_CONVERT_AUX(opcode,hi,lo,rounding_mode) \ ({ \ + union s390x_F128 op = { .i = { hi, lo } }; \ + Double tmp; \ __asm__ volatile ( \ - "ldr 4,%[high]\n\t" \ - "ldr 6,%[low]\n\t" \ - opcode ",0,4," #rounding_mode ",0\n\t" \ - "ipm %[psw]\n\t" : [psw] "=d"(psw) \ - : [high] "f"(hi), [low] "f"(lo) \ - : "cc", "r0", "f4", "f6"); \ + opcode ",%[tmp],%[op]," #rounding_mode ",0\n\t" \ + "ipm %[psw]\n\t" : [psw] "=d"(psw), [tmp] "=f"(tmp) \ + : [op] "f"(op.f) \ + : "cc"); \ psw >> 28; /* cc */ \ }) @@ -1485,16 +1499,16 @@ decode_dfp_rounding_mode(UInt irrm) cc; \ }) -#define S390_CC_FOR_DFP128_UCONVERT_AUX(opcode,hi,lo,rounding_mode) \ - ({ \ - __asm__ volatile ( \ - "ldr 4,%[high]\n\t" \ - "ldr 6,%[low]\n\t" \ - opcode ",0,4," #rounding_mode ",0\n\t" \ - "ipm %[psw]\n\t" : [psw] "=d"(psw) \ - : [high] "f"(hi), [low] "f"(lo) \ - : "cc", "r0", "f4", "f6"); \ - psw >> 28; /* cc */ \ +#define S390_CC_FOR_DFP128_UCONVERT_AUX(opcode,hi,lo,rounding_mode) \ + ({ \ + union s390x_F128 op = { .i = { hi, lo } }; \ + Double tmp; \ + __asm__ volatile ( \ + opcode ",%[tmp],%[op]," #rounding_mode ",0\n\t" \ + "ipm %[psw]\n\t" : [psw] "=d"(psw), [tmp] "=f"(tmp) \ + : [op] "f"(op.f) \ + : "cc"); \ + psw >> 28; /* cc */ \ }) #define S390_CC_FOR_DFP128_UCONVERT(opcode,cc_dep1,cc_dep2,cc_ndep) \ @@ -1539,6 +1553,7 @@ decode_dfp_rounding_mode(UInt irrm) } \ cc; \ }) +#endif /* VGA_s390x */ /* Return the value of the condition code from the supplied thunk parameters. @@ -1620,14 +1635,15 @@ s390_calculate_cc(ULong cc_op, ULong cc_dep1, ULong cc_dep2, ULong cc_ndep) case S390_CC_OP_TEST_UNDER_MASK_8: { UChar value = cc_dep1; UChar mask = cc_dep2; + ULong pc; __asm__ volatile ( - "bras %%r2,1f\n\t" /* %r2 = address of next insn */ + "bras %[pc],1f\n\t" /* pc = address of next insn */ "tm %[value],0\n\t" /* this is skipped, then EXecuted */ - "1: ex %[mask],0(%%r2)\n\t" /* EXecute TM after modifying mask */ - "ipm %[psw]\n\t" : [psw] "=d"(psw) - : [value] "m"(value), [mask] "a"(mask) - : "r2", "cc"); + "1: ex %[mask],0(%[pc])\n\t" /* EXecute TM after modifying mask */ + "ipm %[psw]\n\t" : [psw] "=d"(psw), [pc] "=&a"(pc) + : [value] "Q"(value), [mask] "a"(mask) + : "cc"); return psw >> 28; /* cc */ } @@ -1641,7 +1657,7 @@ s390_calculate_cc(ULong cc_op, ULong cc_dep1, ULong cc_dep2, ULong cc_ndep) "lhi 2,0x10\n\t" "ex 2,%[insn]\n\t" "ipm %[psw]\n\t" : [psw] "=d"(psw) - : [value] "d"(value), [insn] "m"(insn) + : [value] "d"(value), [insn] "R"(insn) : "r1", "r2", "cc"); return psw >> 28; /* cc */ } @@ -1812,11 +1828,11 @@ s390_calculate_cc(ULong cc_op, ULong cc_dep1, ULong cc_dep2, ULong cc_ndep) case S390_CC_OP_PFPO_32: { __asm__ volatile( - "ler 4, %[cc_dep1]\n\t" /* 32 bit FR move */ - "lr 0, %[cc_dep2]\n\t" /* 32 bit GR move */ - ".short 0x010a\n\t" /* PFPO */ - "ipm %[psw]\n\t" : [psw] "=d"(psw) - : [cc_dep1] "f"(cc_dep1), + "ldgr 4, %[cc_dep1]\n\t" /* Load FR from GR */ + "lr 0, %[cc_dep2]\n\t" /* 32 bit GR move */ + ".insn e,0x010a\n\t" /* PFPO */ + "ipm %[psw]\n\t" : [psw] "=d"(psw) + : [cc_dep1] "d"(cc_dep1), [cc_dep2] "d"(cc_dep2) : "r0", "r1", "f4"); return psw >> 28; /* cc */ @@ -1824,11 +1840,11 @@ s390_calculate_cc(ULong cc_op, ULong cc_dep1, ULong cc_dep2, ULong cc_ndep) case S390_CC_OP_PFPO_64: { __asm__ volatile( - "ldr 4, %[cc_dep1]\n\t" - "lr 0, %[cc_dep2]\n\t" /* 32 bit register move */ - ".short 0x010a\n\t" /* PFPO */ - "ipm %[psw]\n\t" : [psw] "=d"(psw) - : [cc_dep1] "f"(cc_dep1), + "ldgr 4, %[cc_dep1]\n\t" + "lr 0, %[cc_dep2]\n\t" /* 32 bit register move */ + ".insn e,0x010a\n\t" /* PFPO */ + "ipm %[psw]\n\t" : [psw] "=d"(psw) + : [cc_dep1] "d"(cc_dep1), [cc_dep2] "d"(cc_dep2) : "r0", "r1", "f4"); return psw >> 28; /* cc */ @@ -1836,13 +1852,13 @@ s390_calculate_cc(ULong cc_op, ULong cc_dep1, ULong cc_dep2, ULong cc_ndep) case S390_CC_OP_PFPO_128: { __asm__ volatile( - "ldr 4,%[cc_dep1]\n\t" - "ldr 6,%[cc_dep2]\n\t" - "lr 0,%[cc_ndep]\n\t" /* 32 bit register move */ - ".short 0x010a\n\t" /* PFPO */ - "ipm %[psw]\n\t" : [psw] "=d"(psw) - : [cc_dep1] "f"(cc_dep1), - [cc_dep2] "f"(cc_dep2), + "ldgr 4,%[cc_dep1]\n\t" + "ldgr 6,%[cc_dep2]\n\t" + "lr 0,%[cc_ndep]\n\t" /* 32 bit register move */ + ".insn e,0x010a\n\t" /* PFPO */ + "ipm %[psw]\n\t" : [psw] "=d"(psw) + : [cc_dep1] "d"(cc_dep1), + [cc_dep2] "d"(cc_dep2), [cc_ndep] "d"(cc_ndep) : "r0", "r1", "f0", "f2", "f4", "f6"); return psw >> 28; /* cc */ @@ -2689,7 +2705,7 @@ s390x_dirtyhelper_vec_op(VexGuestS390XState *guest_state, [arg3] "r" (&guest_v[d->v4]), [zero] "r" (0ULL), - [insn] "m" (the_insn), + [insn] "R" (the_insn), [read_only] "r" (d->read_only) : "cc", "r10", "v16", "v17", "v18", "v19" diff --git a/coregrind/m_debuglog.c b/coregrind/m_debuglog.c index 355c3caf5b..fd6db4beb4 100644 --- a/coregrind/m_debuglog.c +++ b/coregrind/m_debuglog.c @@ -404,7 +404,7 @@ static UInt local_sys_write_stderr ( const HChar* buf, Int n ) ULong __res; __asm__ __volatile__ ( - "svc %b1\n" + "svc %c1\n" : "=d" (r2_res) : "i" (__NR_write), "0" (r2), @@ -424,7 +424,7 @@ static UInt local_sys_getpid ( void ) ULong __res; __asm__ __volatile__ ( - "svc %b1\n" + "svc %c1\n" : "=d" (r2) : "i" (__NR_getpid) : "cc", "memory"); diff --git a/include/valgrind.h.in b/include/valgrind.h.in index aa0b431256..45f6522f34 100644 --- a/include/valgrind.h.in +++ b/include/valgrind.h.in @@ -4748,7 +4748,7 @@ typedef "lgr 1,%1\n\t" /* copy the argvec pointer in r1 */ \ "lgr 7,11\n\t" \ "lgr 11,%2\n\t" \ - ".cfi_def_cfa r11, 0\n\t" + ".cfi_def_cfa 11, 0\n\t" # define VALGRIND_CFI_EPILOGUE \ "lgr 11, 7\n\t" \ ".cfi_restore_state\n\t"