[PATCH] x86: do away with HAVE_AS_NEGATIVE_TRUE

Jan Beulich posted 1 patch 11 months ago
Failed in applying to current master (apply log)
There is a newer version of this series
[PATCH] x86: do away with HAVE_AS_NEGATIVE_TRUE
Posted by Jan Beulich 11 months ago
There's no real need for the associated probing - we can easily convert
to a uniform value without knowing the specific behavior (note also that
the respective comments weren't fully correct and have gone stale). All
we (need to) depend upon is unary ! producing 0 or 1 (and never -1).

For all present purposes yielding a value with all bits set is more
useful.

No difference in generated code.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
---
Unlike in C, there's also binary ! in assembly expressions, and even
binary !!. But those don't get in the way here.

--- a/xen/arch/x86/arch.mk
+++ b/xen/arch/x86/arch.mk
@@ -26,10 +26,6 @@ $(call as-option-add,CFLAGS,CC,"invpcid
 $(call as-option-add,CFLAGS,CC,"movdiri %rax$(comma)(%rax)",-DHAVE_AS_MOVDIR)
 $(call as-option-add,CFLAGS,CC,"enqcmd (%rax)$(comma)%rax",-DHAVE_AS_ENQCMD)
 
-# GAS's idea of true is -1.  Clang's idea is 1
-$(call as-option-add,CFLAGS,CC,\
-    ".if ((1 > 0) < 0); .error \"\";.endif",,-DHAVE_AS_NEGATIVE_TRUE)
-
 # Check to see whether the assmbler supports the .nop directive.
 $(call as-option-add,CFLAGS,CC,\
     ".L1: .L2: .nops (.L2 - .L1)$(comma)9",-DHAVE_AS_NOPS_DIRECTIVE)
--- a/xen/arch/x86/include/asm/alternative.h
+++ b/xen/arch/x86/include/asm/alternative.h
@@ -35,19 +35,19 @@ extern void alternative_branches(void);
 #define alt_repl_e(num)    ".LXEN%=_repl_e"#num
 #define alt_repl_len(num)  "(" alt_repl_e(num) " - " alt_repl_s(num) ")"
 
-/* GAS's idea of true is -1, while Clang's idea is 1. */
-#ifdef HAVE_AS_NEGATIVE_TRUE
-# define AS_TRUE "-"
-#else
-# define AS_TRUE ""
-#endif
+/*
+ * GAS's idea of true is sometimes 1 and sometimes -1, while Clang's idea was
+ * consistently 1 up to 6.x (it matches GAS's now).  Transform it to uniformly
+ * -1 (aka ~0).
+ */
+#define AS_TRUE "-!!"
 
-#define as_max(a, b) "(("a") ^ ((("a") ^ ("b")) & -("AS_TRUE"(("a") < ("b")))))"
+#define as_max(a, b) "(("a") ^ ((("a") ^ ("b")) & "AS_TRUE"(("a") < ("b"))))"
 
 #define OLDINSTR(oldinstr, padding)                              \
     ".LXEN%=_orig_s:\n\t" oldinstr "\n .LXEN%=_orig_e:\n\t"      \
     ".LXEN%=_diff = " padding "\n\t"                             \
-    "mknops ("AS_TRUE"(.LXEN%=_diff > 0) * .LXEN%=_diff)\n\t"    \
+    "mknops ("AS_TRUE"(.LXEN%=_diff > 0) & .LXEN%=_diff)\n\t"    \
     ".LXEN%=_orig_p:\n\t"
 
 #define OLDINSTR_1(oldinstr, n1)                                 \
--- a/xen/arch/x86/include/asm/alternative-asm.h
+++ b/xen/arch/x86/include/asm/alternative-asm.h
@@ -29,17 +29,17 @@
 #endif
 .endm
 
-/* GAS's idea of true is -1, while Clang's idea is 1. */
-#ifdef HAVE_AS_NEGATIVE_TRUE
-# define as_true(x) (-(x))
-#else
-# define as_true(x) (x)
-#endif
+/*
+ * GAS's idea of true is sometimes 1 and sometimes -1, while Clang's idea was
+ * consistently 1 up to 6.x (it matches GAS's now).  Transform it to uniformly
+ * -1 (aka ~0).
+ */
+#define as_true(x) (-!!(x))
 
 #define decl_orig(insn, padding)                  \
  .L\@_orig_s: insn; .L\@_orig_e:                  \
  .L\@_diff = padding;                             \
- mknops (as_true(.L\@_diff > 0) * .L\@_diff);     \
+ mknops (as_true(.L\@_diff > 0) & .L\@_diff);     \
  .L\@_orig_p:
 
 #define orig_len               (.L\@_orig_e       -     .L\@_orig_s)
@@ -49,7 +49,7 @@
 #define decl_repl(insn, nr)     .L\@_repl_s\()nr: insn; .L\@_repl_e\()nr:
 #define repl_len(nr)           (.L\@_repl_e\()nr  -     .L\@_repl_s\()nr)
 
-#define as_max(a, b)           ((a) ^ (((a) ^ (b)) & -as_true((a) < (b))))
+#define as_max(a, b)           ((a) ^ (((a) ^ (b)) & as_true((a) < (b))))
 
 .macro ALTERNATIVE oldinstr, newinstr, feature
     decl_orig(\oldinstr, repl_len(1) - orig_len)
Re: [PATCH] x86: do away with HAVE_AS_NEGATIVE_TRUE
Posted by Andrew Cooper 11 months ago
On 17/05/2023 3:22 pm, Jan Beulich wrote:
> There's no real need for the associated probing - we can easily convert
> to a uniform value without knowing the specific behavior (note also that
> the respective comments weren't fully correct and have gone stale). All
> we (need to) depend upon is unary ! producing 0 or 1 (and never -1).
>
> For all present purposes yielding a value with all bits set is more
> useful.
>
> No difference in generated code.
>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>
> ---
> Unlike in C, there's also binary ! in assembly expressions, and even
> binary !!. But those don't get in the way here.

I had been wanting to do this for a while, but IMO a clearer expression
is to take ((x) & 1) to discard the sign.

It doesn't change any of the logic to use +1 (I don't think), and it's
definitely the more common way for the programmer to think.

~Andrew
Re: [PATCH] x86: do away with HAVE_AS_NEGATIVE_TRUE
Posted by Jan Beulich 11 months ago
On 17.05.2023 19:05, Andrew Cooper wrote:
> On 17/05/2023 3:22 pm, Jan Beulich wrote:
>> There's no real need for the associated probing - we can easily convert
>> to a uniform value without knowing the specific behavior (note also that
>> the respective comments weren't fully correct and have gone stale). All
>> we (need to) depend upon is unary ! producing 0 or 1 (and never -1).
>>
>> For all present purposes yielding a value with all bits set is more
>> useful.
>>
>> No difference in generated code.
>>
>> Signed-off-by: Jan Beulich <jbeulich@suse.com>
>> ---
>> Unlike in C, there's also binary ! in assembly expressions, and even
>> binary !!. But those don't get in the way here.
> 
> I had been wanting to do this for a while, but IMO a clearer expression
> is to take ((x) & 1) to discard the sign.
> 
> It doesn't change any of the logic to use +1 (I don't think), and it's
> definitely the more common way for the programmer to think.

Well, I can certainly switch. It simply seemed to me that with our many
uses of !! elsewhere, using this here as well would only be consistent.
(I did in fact consider the ... & 1 alternative.)

Jan
Re: [PATCH] x86: do away with HAVE_AS_NEGATIVE_TRUE
Posted by Jan Beulich 11 months ago
On 19.05.2023 08:15, Jan Beulich wrote:
> On 17.05.2023 19:05, Andrew Cooper wrote:
>> On 17/05/2023 3:22 pm, Jan Beulich wrote:
>>> There's no real need for the associated probing - we can easily convert
>>> to a uniform value without knowing the specific behavior (note also that
>>> the respective comments weren't fully correct and have gone stale). All
>>> we (need to) depend upon is unary ! producing 0 or 1 (and never -1).
>>>
>>> For all present purposes yielding a value with all bits set is more
>>> useful.
>>>
>>> No difference in generated code.
>>>
>>> Signed-off-by: Jan Beulich <jbeulich@suse.com>
>>> ---
>>> Unlike in C, there's also binary ! in assembly expressions, and even
>>> binary !!. But those don't get in the way here.
>>
>> I had been wanting to do this for a while, but IMO a clearer expression
>> is to take ((x) & 1) to discard the sign.
>>
>> It doesn't change any of the logic to use +1 (I don't think), and it's
>> definitely the more common way for the programmer to think.
> 
> Well, I can certainly switch. It simply seemed to me that with our many
> uses of !! elsewhere, using this here as well would only be consistent.
> (I did in fact consider the ... & 1 alternative.)

Before even starting with this - you do realize that the C macro
(AS_TRUE) expands to just a prefix for the expression to be dealt
with? That would then become "1 & ", which I have to admit I find
a little odd. The alternative of making this a more ordinary macro
(with a parameter) would likely be more intrusive. Plus I assume
you had a reason to do it the way it is right now (and I might end
up figuring that reason the hard way when trying to change things).

Jan