Port-vax archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Silly gcc bugs
On Sun, 14 Feb 2016, Maciej W. Rozycki wrote:
> I've checked the generated assembly and I think it is correct although I
> can't easily verify it at the run time right now, so I'll appreciate if
> you try this change and let me know if the code that failed to build also
> works correctly.
>
> If it works for your case, then it would be nice to put it through full
> GCC regression testing too, however doing that in a cross-compilation
> environment is tricky and I'm not set up for native testing with the
> VAX/Linux port, it's simply too immature. So if someone steps in and does
> that, then I'll appreciate it -- in a native environment it's as easy as
> running `make check' (or maybe `make -C gcc check' to exclude libraries
> from being tested in return for a quicker run) in your build tree.
Martin was kind enough to put it through testing (thanks!) and it choke
on the offset being output by GCC from `*addsi4_mova' as an immediate,
that is with `$' prepended. That didn't trigger with my previous testing
as gchecksum.s didn't include any output generated from the `*addsi4_mova'
insn, however it can be easily reproduced with code like (the asm only
needed to force data into registers in the most compact way):
int add(int x, int y)
{
asm("" : "+r" (x), "+r" (y));
return x + 4 * y + 8;
}
Here's a patch update which corrects it, by adding a new operand code
that prints a constant with the `$' prefix omitted. There's no existing
code that could serve this purpose (`x' is close, present in HEAD only and
not in 4.1, however I'd keep it decimal for consistency), so I added a new
one, placing it such as not to cause a conflict with HEAD. TBH I think it
would be nice if these operand codes were actually documented like with
the other ports. ;)
I hope this was the last issue, but please do let me know even if not.
Interestingly enough if `4' in the function above is changed to `2', then
`*addsi4_mova' is not matched for some reason and instead of a single
MOVAW instruction a longer sequence using ADDL2 followed by MOVAB is
produced. The lengths of MOVAW and MOVAB here are both the same and both
use the indexed addressing mode, so I can't see how the longer sequence
can have any benefit, or indeed no loss. I smell some costs may need
tweaking, and maybe an insn for `ashift' rather than `mult' added too.
Just a side note though.
2016-02-14 Maciej W. Rozycki <macro%linux-mips.org@localhost>
gcc/
* config/vax/vax.c (print_operand): Add the `o' operand code.
* config/vax/predicates.md (const_248_operand): New predicate.
* config/vax/vax.md (*addsi3_mova, *addsi4_mova): New insns.
Maciej
gcc-4.1.2-vax-mova.patch
Index: gcc-4.1.2/gcc/config/vax/predicates.md
===================================================================
--- gcc-4.1.2.orig/gcc/config/vax/predicates.md
+++ gcc-4.1.2/gcc/config/vax/predicates.md
@@ -102,3 +102,11 @@
(and (match_code "const_int,const_double,subreg,reg,mem")
(and (match_operand:DI 0 "general_operand" "")
(not (match_operand:DI 0 "illegal_addsub_di_memory_operand")))))
+
+;; Match 2, 4, or 8. Used for mova multiplicands.
+(define_predicate "const_248_operand"
+ (match_code "const_int")
+{
+ HOST_WIDE_INT i = INTVAL (op);
+ return i == 2 || i == 4 || i == 8;
+})
Index: gcc-4.1.2/gcc/config/vax/vax.c
===================================================================
--- gcc-4.1.2.orig/gcc/config/vax/vax.c
+++ gcc-4.1.2/gcc/config/vax/vax.c
@@ -425,6 +425,8 @@ print_operand (FILE *file, rtx x, int co
fputs (REGISTER_PREFIX, file);
else if (code == 'C')
fputs (rev_cond_name (x), file);
+ else if (code == 'o' && CONST_INT_P (x))
+ fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
else if (code == 'D' && CONST_INT_P (x) && INTVAL (x) < 0)
fprintf (file, "$" NEG_HWI_PRINT_HEX16, INTVAL (x));
else if (code == 'P' && CONST_INT_P (x))
Index: gcc-4.1.2/gcc/config/vax/vax.md
===================================================================
--- gcc-4.1.2.orig/gcc/config/vax/vax.md
+++ gcc-4.1.2/gcc/config/vax/vax.md
@@ -405,6 +405,54 @@
(match_operand:DI 2 "general_operand" "Fsro,Fs")))]
"!TARGET_QMATH"
"* return vax_output_int_add (insn, operands, DImode);")
+
+;; Scaled additions using mova, needed for virtual register instantiation.
+(define_insn "*addsi3_mova"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+ (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
+ (match_operand 2 "const_248_operand" "n"))
+ (match_operand:SI 3 "register_operand" "r")))]
+ ""
+ "*
+{
+ int i = INTVAL (operands[2]);
+
+ switch (i)
+ {
+ case 2:
+ return \"movaw (%3)[%1],%0\";
+ case 4:
+ return \"moval (%3)[%1],%0\";
+ case 8:
+ return \"movaq (%3)[%1],%0\";
+ default:
+ gcc_unreachable ();
+ }
+}")
+
+(define_insn "*addsi4_mova"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+ (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
+ (match_operand 2 "const_248_operand" "n"))
+ (match_operand:SI 3 "register_operand" "r"))
+ (match_operand:SI 4 "immediate_operand" "i")))]
+ ""
+ "*
+{
+ int i = INTVAL (operands[2]);
+
+ switch (i)
+ {
+ case 2:
+ return \"movaw %o4(%3)[%1],%0\";
+ case 4:
+ return \"moval %o4(%3)[%1],%0\";
+ case 8:
+ return \"movaq %o4(%3)[%1],%0\";
+ default:
+ gcc_unreachable ();
+ }
+}")
;;- All kinds of subtract instructions.
Home |
Main Index |
Thread Index |
Old Index