Re: [OpenRISC] [PATCH v2 4/5] or1k: Initial support for FPU

2019-07-03 Thread Segher Boessenkool
On Thu, Jul 04, 2019 at 07:19:56AM +0900, Stafford Horne wrote:
> On Wed, Jul 03, 2019 at 09:09:51PM +0200, Richard Henderson wrote:
> > On 7/3/19 5:43 PM, Segher Boessenkool wrote:
> > >> @@ -212,6 +214,7 @@ enum reg_class
> > >>  #define REG_CLASS_CONTENTS  \
> > >>  { { 0x, 0x },   \
> > >>{ SIBCALL_REGS_MASK,   0 },   \
> > >> +  { 0x7efe, 0x },   \
> > > 
> > > Above you said r0, r30, r31 are excluded, but this is r0, r8, r30, or
> > > in GCC register numbers, 0, 8, and 31?  You probably should mention r8
> > > somewhere (it's because it is the last arg, this avoid problems, I 
> > > guess?),
> > > and the 30/31 thing is confused some way.  Maybe it is all just that one
> > > documentation line :-)
> > 
> > ... and if r8 is excluded because of arguments, I suspect that this is the
> > wrong fix, as there's nothing inherently wrong with r7:r8 or r8:r9 as a 
> > pair,
> > at least that I can see.
> > 
> > Perhaps function_arg and/or function_arg_advance is the right place for a 
> > fix?
> > The calling convention says that 64-bit arguments are not split across
> > registers+stack, so you already shouldn't have seen (r8, [sp+0]) as a pair.
> 
> I will double check, the mask may be wrong.  It should not matter about the
> function args.
> 
> I didn't see any issue that caused me to add r8.  So I may have just masked 
> thw
> rong bit thinking it's r31.  Is there something worng with what I did?
> 
> The mask is 0x7efe, and names should corresbond to this name list?
> 
> #define REGISTER_NAMES {
>   "r0",   "r1",   "r2",   "r3",   "r4",   "r5",   "r6",   "r7",  # 7e, excl r0
>   "r8",   "r9",   "r10",  "r11",  "r12",  "r13",  "r14",  "r15", # ff, excl 
> none
>   "r17",  "r19",  "r21",  "r23",  "r25",  "r27",  "r29",  "r31", # fe, excl 
> r31
>   "r16",  "r18",  "r20",  "r22",  "r24",  "r26",  "r28",  "r30", # fe, excl 
> r30
>   "?ap",  "?fp",  "?sr_f" }
> 
> Do I have it backwards?  With an endian issue?

Yes :-)  0x0001 is reg 0 (r0), 0x8000 is reg 31 (r30).


Segher


Re: [OpenRISC] [PATCH v2 4/5] or1k: Initial support for FPU

2019-07-03 Thread Stafford Horne
On Wed, Jul 03, 2019 at 09:09:51PM +0200, Richard Henderson wrote:
> On 7/3/19 5:43 PM, Segher Boessenkool wrote:
> >> @@ -212,6 +214,7 @@ enum reg_class
> >>  #define REG_CLASS_CONTENTS  \
> >>  { { 0x, 0x }, \
> >>{ SIBCALL_REGS_MASK,   0 }, \
> >> +  { 0x7efe, 0x }, \
> > 
> > Above you said r0, r30, r31 are excluded, but this is r0, r8, r30, or
> > in GCC register numbers, 0, 8, and 31?  You probably should mention r8
> > somewhere (it's because it is the last arg, this avoid problems, I guess?),
> > and the 30/31 thing is confused some way.  Maybe it is all just that one
> > documentation line :-)
> 
> ... and if r8 is excluded because of arguments, I suspect that this is the
> wrong fix, as there's nothing inherently wrong with r7:r8 or r8:r9 as a pair,
> at least that I can see.
> 
> Perhaps function_arg and/or function_arg_advance is the right place for a fix?
> The calling convention says that 64-bit arguments are not split across
> registers+stack, so you already shouldn't have seen (r8, [sp+0]) as a pair.

I will double check, the mask may be wrong.  It should not matter about the
function args.

I didn't see any issue that caused me to add r8.  So I may have just masked thw
rong bit thinking it's r31.  Is there something worng with what I did?

The mask is 0x7efe, and names should corresbond to this name list?

#define REGISTER_NAMES {
  "r0",   "r1",   "r2",   "r3",   "r4",   "r5",   "r6",   "r7",  # 7e, excl r0
  "r8",   "r9",   "r10",  "r11",  "r12",  "r13",  "r14",  "r15", # ff, excl none
  "r17",  "r19",  "r21",  "r23",  "r25",  "r27",  "r29",  "r31", # fe, excl r31
  "r16",  "r18",  "r20",  "r22",  "r24",  "r26",  "r28",  "r30", # fe, excl r30
  "?ap",  "?fp",  "?sr_f" }

Do I have it backwards?  With an endian issue?

-Stafford


Re: [PATCH v2 4/5] or1k: Initial support for FPU

2019-07-03 Thread Stafford Horne
On Wed, Jul 03, 2019 at 10:43:01AM -0500, Segher Boessenkool wrote:
> Hi Stafford,
> 
> On Wed, Jul 03, 2019 at 12:33:50PM +0900, Stafford Horne wrote:
> > +case 'd':
> > +  if (REG_P (x))
> > + if (GET_MODE (x) == DFmode || GET_MODE (x) == DImode)
> > +   fprintf (file, "%s,%s", reg_names[REGNO (operand)],
> > +   reg_names[REGNO (operand) + 1]);
> > + else
> > +   fprintf (file, "%s", reg_names[REGNO (operand)]);
> > +  else
> 
> The coding conventions says to use braces around nested conditionals.

Right I will fix that.  Interestingly the indentation is correct just missing
the braces.
 
> > @@ -212,6 +214,7 @@ enum reg_class
> >  #define REG_CLASS_CONTENTS  \
> >  { { 0x, 0x },  \
> >{ SIBCALL_REGS_MASK,   0 },  \
> > +  { 0x7efe, 0x },  \
> 
> Above you said r0, r30, r31 are excluded, but this is r0, r8, r30, or
> in GCC register numbers, 0, 8, and 31?  You probably should mention r8
> somewhere (it's because it is the last arg, this avoid problems, I guess?),
> and the 30/31 thing is confused some way.  Maybe it is all just that one
> documentation line :-)
>
> > +;  d - double pair base registers (excludes r0, r30 and r31 which overflow)

Hmm, maybe I messed up the mask.  It should be r0, r30 and r31.  Register pairs
can be a base register (rX) with a +1 or +2 offset second register.

Registers not allowed
  - r0, because its reserved for hardwired zero and doesn't work as a double
zero when paired with a general register.
  - r31, because it cant pair with r32 or r33 (those are overflows)
  - r30, because it cant work when paried with r32 (its an overflow), it would
work with r31, but GCC will not generate that pair anyway.

-Stafford


Re: [OpenRISC] [PATCH v2 4/5] or1k: Initial support for FPU

2019-07-03 Thread Richard Henderson
On 7/3/19 5:43 PM, Segher Boessenkool wrote:
>> @@ -212,6 +214,7 @@ enum reg_class
>>  #define REG_CLASS_CONTENTS  \
>>  { { 0x, 0x },   \
>>{ SIBCALL_REGS_MASK,   0 },   \
>> +  { 0x7efe, 0x },   \
> 
> Above you said r0, r30, r31 are excluded, but this is r0, r8, r30, or
> in GCC register numbers, 0, 8, and 31?  You probably should mention r8
> somewhere (it's because it is the last arg, this avoid problems, I guess?),
> and the 30/31 thing is confused some way.  Maybe it is all just that one
> documentation line :-)

... and if r8 is excluded because of arguments, I suspect that this is the
wrong fix, as there's nothing inherently wrong with r7:r8 or r8:r9 as a pair,
at least that I can see.

Perhaps function_arg and/or function_arg_advance is the right place for a fix?
The calling convention says that 64-bit arguments are not split across
registers+stack, so you already shouldn't have seen (r8, [sp+0]) as a pair.


r~


Re: [PATCH v2 4/5] or1k: Initial support for FPU

2019-07-03 Thread Segher Boessenkool
Hi Stafford,

On Wed, Jul 03, 2019 at 12:33:50PM +0900, Stafford Horne wrote:
> +case 'd':
> +  if (REG_P (x))
> +   if (GET_MODE (x) == DFmode || GET_MODE (x) == DImode)
> + fprintf (file, "%s,%s", reg_names[REGNO (operand)],
> + reg_names[REGNO (operand) + 1]);
> +   else
> + fprintf (file, "%s", reg_names[REGNO (operand)]);
> +  else

The coding conventions says to use braces around nested conditionals.

> @@ -212,6 +214,7 @@ enum reg_class
>  #define REG_CLASS_CONTENTS  \
>  { { 0x, 0x },\
>{ SIBCALL_REGS_MASK,   0 },\
> +  { 0x7efe, 0x },\

Above you said r0, r30, r31 are excluded, but this is r0, r8, r30, or
in GCC register numbers, 0, 8, and 31?  You probably should mention r8
somewhere (it's because it is the last arg, this avoid problems, I guess?),
and the 30/31 thing is confused some way.  Maybe it is all just that one
documentation line :-)

> +;  d - double pair base registers (excludes r0, r30 and r31 which overflow)


Segher


[PATCH v2 4/5] or1k: Initial support for FPU

2019-07-02 Thread Stafford Horne
This adds support for OpenRISC hardware floating point instructions.
This is enabled with the -mhard-float option.

Double-prevision floating point operations work using register pairing as
specified in: https://openrisc.io/proposals/orfpx64a32.  This has just been
added in the OpenRISC architecture specification 1.3.
This is enabled with the -mdouble-float option.

Not all architectures support unordered comparisons so an option,
-munordered-float is added.

Currently OpenRISC does not support sf/df or df/sf conversions, but this has
also just been added in architecture specification 1.3.

gcc/ChangeLog:

* config.gcc (or1k*-*-*): Add mhard-float, mdouble-float, msoft-float
and munordered-float validations.
* config/or1k/constraints.md (d): New register constraint.
* config/or1k/predicates.md (fp_comparison_operator): New.
* config/or1k/or1k.c (or1k_print_operand): Add support for printing 'd'
operands.
(or1k_expand_compare): Normalize unordered comparisons.
* config/or1k/or1k.h (reg_class): Define DOUBLE_REGS.
(REG_CLASS_NAMES): Add "DOUBLE_REGS".
(REG_CLASS_CONTENTS): Add contents for DOUBLE_REGS.
* config/or1k/or1k.md (type): Add fpu.
(fpu): New instruction reservation.
(F, f, fr, fi, FI, FOP, fop): New.
(3): New ALU instruction definition.
(float2): New conversion instruction definition.
(fix_trunc2): New conversion instruction definition.
(fpcmpcc): New code iterator.
(*sf_fp_insn): New instruction definition.
(cstore4): New expand definition.
(cbranch4): New expand definition.
* config/or1k/or1k.opt (msoft-float, mhard-float, mdouble-float,
munordered-float): New options.
* doc/invoke.texi: Document msoft-float, mhard-float, mdouble-float and
munordered-float.
---
Changes since v1:
 - User register pairs for 64-bit ops. See or1k_print_operand 

 gcc/config.gcc |   1 +
 gcc/config/or1k/constraints.md |   4 ++
 gcc/config/or1k/or1k.c |  36 ++-
 gcc/config/or1k/or1k.h |   3 +
 gcc/config/or1k/or1k.md| 111 -
 gcc/config/or1k/or1k.opt   |  22 +++
 gcc/config/or1k/predicates.md  |   5 ++
 gcc/doc/invoke.texi|  21 +++
 8 files changed, 199 insertions(+), 4 deletions(-)

diff --git a/gcc/config.gcc b/gcc/config.gcc
index aeab8b4544e..1678109131f 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -2579,6 +2579,7 @@ or1k*-*-*)
case ${or1k_multilib} in
mcmov | msext | msfimm | \
mror | mrori | \
+   mhard-float | mdouble-float | munordered-float | msoft-float | \
mhard-div | mhard-mul | \
msoft-div | msoft-mul )

TM_MULTILIB_CONFIG="${TM_MULTILIB_CONFIG},${or1k_multilib}"
diff --git a/gcc/config/or1k/constraints.md b/gcc/config/or1k/constraints.md
index 93da8c058c6..8cac7eb5329 100644
--- a/gcc/config/or1k/constraints.md
+++ b/gcc/config/or1k/constraints.md
@@ -24,6 +24,7 @@
 
 ; We use:
 ;  c - sibcall registers
+;  d - double pair base registers (excludes r0, r30 and r31 which overflow)
 ;  I - constant signed 16-bit
 ;  K - constant unsigned 16-bit
 ;  M - constant signed 16-bit shifted left 16-bits (l.movhi)
@@ -32,6 +33,9 @@
 (define_register_constraint "c" "SIBCALL_REGS"
   "Registers which can hold a sibling call address")
 
+(define_register_constraint "d" "DOUBLE_REGS"
+  "Registers which can be used for double reg pairs.")
+
 ;; Immediates
 (define_constraint "I"
   "A signed 16-bit immediate in the range -32768 to 32767."
diff --git a/gcc/config/or1k/or1k.c b/gcc/config/or1k/or1k.c
index 54c9e804ea5..d90826b75ca 100644
--- a/gcc/config/or1k/or1k.c
+++ b/gcc/config/or1k/or1k.c
@@ -1226,6 +1226,17 @@ or1k_print_operand (FILE *file, rtx x, int code)
output_operand_lossage ("invalid %%H value");
   break;
 
+case 'd':
+  if (REG_P (x))
+ if (GET_MODE (x) == DFmode || GET_MODE (x) == DImode)
+   fprintf (file, "%s,%s", reg_names[REGNO (operand)],
+   reg_names[REGNO (operand) + 1]);
+ else
+   fprintf (file, "%s", reg_names[REGNO (operand)]);
+  else
+   output_operand_lossage ("invalid %%d value");
+  break;
+
 case 'h':
   print_reloc (file, x, 0, RKIND_HI);
   break;
@@ -1435,21 +1446,42 @@ void
 or1k_expand_compare (rtx *operands)
 {
   rtx sr_f = gen_rtx_REG (BImode, SR_F_REGNUM);
+  rtx_code cmp_code = GET_CODE (operands[0]);
+  bool flag_check_ne = true;
 
   /* The RTL may receive an immediate in argument 1 of the compare, this is not
  supported unless we have l.sf*i instructions, force them into registers.  
*/
   if (!TARGET_SFIMM)
 XEXP (operands[0], 1) = force_reg (SImode, XEXP (operands[0], 1));
 
+  /* Normalize comparison operators to ones OpenRISC support.  */
+