[PATCH] MIPS/gas: Fix order of instructions in LI macro expansion

Paul Hua paul.hua.gm@gmail.com
Tue Jun 25 12:29:00 GMT 2019


ok.

On Thu, Jun 20, 2019 at 6:55 AM Faraz Shahbazker
<fshahbazker@wavecomp.com> wrote:
>
> When MTHC1 instruction is paired with MTC1 to write a value to a
> 64-bit FPR, the MTC1 must be executed first, because the semantic
> definition of MTC1 is not aware that software will be using an MTHC1
> to complete the operation, and sets the upper half of the 64-bit FPR
> to an UNPREDICTABLE value[1].
>
> Fix the order of MTHC1 and MTC1 instructions in LI macro expansion.
> Modify the expansions to exploit moves from $zero directly by-passing
> the use of $AT, where ever possible.
>
> [1] "MIPS Architecture for Programmers Volume II-A: The MIPS32
>      Instruction Set Manual", Wave Computing, Inc., Document
>      Number: MD00086, Revision 5.04, December 11, 2013, Section 3.2
>      "Alphabetical List of Instructions", pp. 217.
>
> gas/
>         * config/tc-mips.c (macro) <M_LI>: Re-order MTHC1 with
>         respect to MTC1 and use $0 for either part where possible.
>         * testsuite/gas/mips/li-d.s: Add test cases for non-zero
>         words in double precision constants.
>         * testsuite/gas/mips/li-d.d: Update reference output.
>         * testsuite/gas/mips/micromips@isa-override-1.d: Likewise.
>         * testsuite/gas/mips/mips32r2@isa-override-1.d: Likewise.
>         * testsuite/gas/mips/mips64r2@isa-override-1.d: Likewise.
> ---
>
> Notes:
>     https://s3-eu-west-1.amazonaws.com/downloads-mips/documents/MD00086-2B-MIPS32BIS-AFP-05.04.pdf
>
>  gas/config/tc-mips.c                              | 40 +++++++++++++-----
>  gas/testsuite/gas/mips/li-d.d                     | 51 +++++++++++++++++++----
>  gas/testsuite/gas/mips/li-d.s                     | 39 +++++++++++++++++
>  gas/testsuite/gas/mips/micromips@isa-override-1.d | 12 +++---
>  gas/testsuite/gas/mips/mips32r2@isa-override-1.d  | 12 +++---
>  gas/testsuite/gas/mips/mips64r2@isa-override-1.d  | 12 +++---
>  6 files changed, 129 insertions(+), 37 deletions(-)
>
> diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
> index 0f0ace5..671d74a 100644
> --- a/gas/config/tc-mips.c
> +++ b/gas/config/tc-mips.c
> @@ -12780,20 +12780,28 @@ macro (struct mips_cl_insn *ip, char *str)
>           OFFSET_EXPR.  */
>        if (imm_expr.X_op == O_constant)
>         {
> -         used_at = 1;
> -         load_register (AT, &imm_expr, FPR_SIZE == 64);
> +         tempreg = ZERO;
> +         if (((FPR_SIZE == 64 && GPR_SIZE == 64)
> +              || !ISA_HAS_MXHC1 (mips_opts.isa))
> +             && imm_expr.X_add_number != 0)
> +           {
> +             used_at = 1;
> +             tempreg = AT;
> +             load_register (AT, &imm_expr, FPR_SIZE == 64);
> +           }
>           if (FPR_SIZE == 64 && GPR_SIZE == 64)
> -           macro_build (NULL, "dmtc1", "t,S", AT, op[0]);
> +           macro_build (NULL, "dmtc1", "t,S", tempreg, op[0]);
>           else
>             {
> -             if (ISA_HAS_MXHC1 (mips_opts.isa))
> -               macro_build (NULL, "mthc1", "t,G", AT, op[0]);
> -             else if (FPR_SIZE != 32)
> -               as_bad (_("Unable to generate `%s' compliant code "
> -                         "without mthc1"),
> -                       (FPR_SIZE == 64) ? "fp64" : "fpxx");
> -             else
> -               macro_build (NULL, "mtc1", "t,G", AT, op[0] + 1);
> +             if (!ISA_HAS_MXHC1 (mips_opts.isa))
> +               {
> +                 if (FPR_SIZE != 32)
> +                   as_bad (_("Unable to generate `%s' compliant code "
> +                             "without mthc1"),
> +                           (FPR_SIZE == 64) ? "fp64" : "fpxx");
> +                 else
> +                   macro_build (NULL, "mtc1", "t,G", tempreg, op[0] + 1);
> +               }
>               if (offset_expr.X_op == O_absent)
>                 macro_build (NULL, "mtc1", "t,G", 0, op[0]);
>               else
> @@ -12802,6 +12810,16 @@ macro (struct mips_cl_insn *ip, char *str)
>                   load_register (AT, &offset_expr, 0);
>                   macro_build (NULL, "mtc1", "t,G", AT, op[0]);
>                 }
> +             if (ISA_HAS_MXHC1 (mips_opts.isa))
> +               {
> +                 if (imm_expr.X_add_number != 0)
> +                   {
> +                     used_at = 1;
> +                     tempreg = AT;
> +                     load_register (AT, &imm_expr, 0);
> +                   }
> +                 macro_build (NULL, "mthc1", "t,G", tempreg, op[0]);
> +               }
>             }
>           break;
>         }
> diff --git a/gas/testsuite/gas/mips/li-d.d b/gas/testsuite/gas/mips/li-d.d
> index ca24570..9c569a1 100644
> --- a/gas/testsuite/gas/mips/li-d.d
> +++ b/gas/testsuite/gas/mips/li-d.d
> @@ -10,22 +10,57 @@
>  Disassembly of section \.text:
>  [0-9a-f]+ <[^>]*> li   v(0|1),0
>  [0-9a-f]+ <[^>]*> move v(1|0),zero
> -[0-9a-f]+ <[^>]*> li   at,0
> +[0-9a-f]+ <[^>]*> mtc1 zero,\$f1
> +[0-9a-f]+ <[^>]*> mtc1 zero,\$f0
> +[0-9a-f]+ <[^>]*> mtc1 zero,\$f1
> +[0-9a-f]+ <[^>]*> mtc1 zero,\$f0
> +[0-9a-f]+ <[^>]*> ldc1 \$f0,0\(gp\)
> +[0-9a-f]+ <[^>]*> mtc1 zero,\$f0
> +[0-9a-f]+ <[^>]*> mthc1        zero,\$f0
> +[0-9a-f]+ <[^>]*> mtc1 zero,\$f0
> +[0-9a-f]+ <[^>]*> mthc1        zero,\$f0
> +[0-9a-f]+ <[^>]*> mtc1 zero,\$f0
> +[0-9a-f]+ <[^>]*> mthc1        zero,\$f0
> +[0-9a-f]+ <[^>]*> dmtc1        zero,\$f0
> +[0-9a-f]+ <[^>]*> lui  v[01],0x3ff0
> +[0-9a-f]+ <[^>]*> move v[01],zero
> +[0-9a-f]+ <[^>]*> lui  at,0x3ff0
>  [0-9a-f]+ <[^>]*> mtc1 at,\$f1
>  [0-9a-f]+ <[^>]*> mtc1 zero,\$f0
> -[0-9a-f]+ <[^>]*> li   at,0
> +[0-9a-f]+ <[^>]*> lui  at,0x3ff0
>  [0-9a-f]+ <[^>]*> mtc1 at,\$f1
>  [0-9a-f]+ <[^>]*> mtc1 zero,\$f0
> -[0-9a-f]+ <[^>]*> ldc1 \$f0,0\(gp\)
> -[0-9a-f]+ <[^>]*> li   at,0
> -[0-9a-f]+ <[^>]*> mthc1        at,\$f0
> +[0-9a-f]+ <[^>]*> ldc1 \$f0,(0|8)\(gp\)
>  [0-9a-f]+ <[^>]*> mtc1 zero,\$f0
> -[0-9a-f]+ <[^>]*> li   at,0
> +[0-9a-f]+ <[^>]*> lui  at,0x3ff0
>  [0-9a-f]+ <[^>]*> mthc1        at,\$f0
>  [0-9a-f]+ <[^>]*> mtc1 zero,\$f0
> -[0-9a-f]+ <[^>]*> li   at,0
> +[0-9a-f]+ <[^>]*> lui  at,0x3ff0
>  [0-9a-f]+ <[^>]*> mthc1        at,\$f0
>  [0-9a-f]+ <[^>]*> mtc1 zero,\$f0
> -[0-9a-f]+ <[^>]*> li   at,0
> +[0-9a-f]+ <[^>]*> lui  at,0x3ff0
> +[0-9a-f]+ <[^>]*> mthc1        at,\$f0
> +[0-9a-f]+ <[^>]*> li   at,0xffc0
> +[0-9a-f]+ <[^>]*> dsll32       at,at,0xe
> +[0-9a-f]+ <[^>]*> dmtc1        at,\$f0
> +[0-9a-f]+ <[^>]*> li   v[01],0
> +[0-9a-f]+ <[^>]*> li   v[01],4250
> +[0-9a-f]+ <[^>]*> mtc1 zero,\$f1
> +[0-9a-f]+ <[^>]*> li   at,4250
> +[0-9a-f]+ <[^>]*> mtc1 at,\$f0
> +[0-9a-f]+ <[^>]*> mtc1 zero,\$f1
> +[0-9a-f]+ <[^>]*> li   at,4250
> +[0-9a-f]+ <[^>]*> mtc1 at,\$f0
> +[0-9a-f]+ <[^>]*> ldc1 \$f0,(0|16)\(gp\)
> +[0-9a-f]+ <[^>]*> li   at,4250
> +[0-9a-f]+ <[^>]*> mtc1 at,\$f0
> +[0-9a-f]+ <[^>]*> mthc1        zero,\$f0
> +[0-9a-f]+ <[^>]*> li   at,4250
> +[0-9a-f]+ <[^>]*> mtc1 at,\$f0
> +[0-9a-f]+ <[^>]*> mthc1        zero,\$f0
> +[0-9a-f]+ <[^>]*> li   at,4250
> +[0-9a-f]+ <[^>]*> mtc1 at,\$f0
> +[0-9a-f]+ <[^>]*> mthc1        zero,\$f0
> +[0-9a-f]+ <[^>]*> li   at,4250
>  [0-9a-f]+ <[^>]*> dmtc1        at,\$f0
>         \.\.\.
> diff --git a/gas/testsuite/gas/mips/li-d.s b/gas/testsuite/gas/mips/li-d.s
> index 8578097..561f2bc 100644
> --- a/gas/testsuite/gas/mips/li-d.s
> +++ b/gas/testsuite/gas/mips/li-d.s
> @@ -1,6 +1,7 @@
>  # Source file used to test the li macro.
>
>  foo:
> +       # Both words zero
>         .set mips1
>         .set fp=32
>         li.d $2, 0
> @@ -19,6 +20,44 @@ foo:
>         .set mips3
>         li.d $f0, 0
>
> +       # Only upper 16 bits of 64 non-zero
> +       .set mips1
> +       .set fp=32
> +       li.d $2, 1.0
> +       li.d $f0, 1.0
> +       .set mips2
> +       li.d $f0, 1.0
> +       .set fp=xx
> +       li.d $f0, 1.0
> +       .set mips32r2
> +       .set fp=32
> +       li.d $f0, 1.0
> +       .set fp=xx
> +       li.d $f0, 1.0
> +       .set fp=64
> +       li.d $f0, 1.0
> +       .set mips3
> +       li.d $f0, 1.0
> +
> +       # Only lower 16 bits of 64 non-zero
> +       .set mips1
> +       .set fp=32
> +       li.d $2, 2.1e-320
> +       li.d $f0, 2.1e-320
> +       .set mips2
> +       li.d $f0, 2.1e-320
> +       .set fp=xx
> +       li.d $f0, 2.1e-320
> +       .set mips32r2
> +       .set fp=32
> +       li.d $f0, 2.1e-320
> +       .set fp=xx
> +       li.d $f0, 2.1e-320
> +       .set fp=64
> +       li.d $f0, 2.1e-320
> +       .set mips3
> +       li.d $f0, 2.1e-320
> +
>  # Force at least 8 (non-delay-slot) zero bytes, to make 'objdump' print ...
>         .align  2
>         .space  8
> diff --git a/gas/testsuite/gas/mips/micromips@isa-override-1.d b/gas/testsuite/gas/mips/micromips@isa-override-1.d
> index e600ff8..3403696 100644
> --- a/gas/testsuite/gas/mips/micromips@isa-override-1.d
> +++ b/gas/testsuite/gas/mips/micromips@isa-override-1.d
> @@ -11,10 +11,10 @@ Disassembly of section \.text:
>  [0-9a-f]+ <[^>]*> 41a1 89ab    lui     at,0x89ab
>  [0-9a-f]+ <[^>]*> 0022 1290    or      v0,v0,at
>  [0-9a-f]+ <[^>]*> bc44 0000    ldc1    \$f2,0\(a0\)
> -[0-9a-f]+ <[^>]*> 41a1 3ff0    lui     at,0x3ff0
> -[0-9a-f]+ <[^>]*> 5422 383b    mthc1   at,\$f2
>  [0-9a-f]+ <[^>]*> 41a1 89ab    lui     at,0x89ab
>  [0-9a-f]+ <[^>]*> 5422 283b    mtc1    at,\$f2
> +[0-9a-f]+ <[^>]*> 41a1 3ff0    lui     at,0x3ff0
> +[0-9a-f]+ <[^>]*> 5422 383b    mthc1   at,\$f2
>  [0-9a-f]+ <[^>]*> dc44 0000    ld      v0,0\(a0\)
>  [0-9a-f]+ <[^>]*> 5020 89ab    li      at,0x89ab
>  [0-9a-f]+ <[^>]*> 5821 8000    dsll    at,at,0x10
> @@ -34,17 +34,17 @@ Disassembly of section \.text:
>  [0-9a-f]+ <[^>]*> 41a1 89ab    lui     at,0x89ab
>  [0-9a-f]+ <[^>]*> 0022 1290    or      v0,v0,at
>  [0-9a-f]+ <[^>]*> bc44 0000    ldc1    \$f2,0\(a0\)
> -[0-9a-f]+ <[^>]*> 41a1 3ff0    lui     at,0x3ff0
> -[0-9a-f]+ <[^>]*> 5422 383b    mthc1   at,\$f2
>  [0-9a-f]+ <[^>]*> 41a1 89ab    lui     at,0x89ab
>  [0-9a-f]+ <[^>]*> 5422 283b    mtc1    at,\$f2
> +[0-9a-f]+ <[^>]*> 41a1 3ff0    lui     at,0x3ff0
> +[0-9a-f]+ <[^>]*> 5422 383b    mthc1   at,\$f2
>  [0-9a-f]+ <[^>]*> fc44 0000    lw      v0,0\(a0\)
>  [0-9a-f]+ <[^>]*> fc64 0004    lw      v1,4\(a0\)
>  [0-9a-f]+ <[^>]*> 41a1 89ab    lui     at,0x89ab
>  [0-9a-f]+ <[^>]*> 0022 1290    or      v0,v0,at
>  [0-9a-f]+ <[^>]*> bc44 0000    ldc1    \$f2,0\(a0\)
> -[0-9a-f]+ <[^>]*> 41a1 3ff0    lui     at,0x3ff0
> -[0-9a-f]+ <[^>]*> 5422 383b    mthc1   at,\$f2
>  [0-9a-f]+ <[^>]*> 41a1 89ab    lui     at,0x89ab
>  [0-9a-f]+ <[^>]*> 5422 283b    mtc1    at,\$f2
> +[0-9a-f]+ <[^>]*> 41a1 3ff0    lui     at,0x3ff0
> +[0-9a-f]+ <[^>]*> 5422 383b    mthc1   at,\$f2
>         \.\.\.
> diff --git a/gas/testsuite/gas/mips/mips32r2@isa-override-1.d b/gas/testsuite/gas/mips/mips32r2@isa-override-1.d
> index 0ab21b9..0dc753a 100644
> --- a/gas/testsuite/gas/mips/mips32r2@isa-override-1.d
> +++ b/gas/testsuite/gas/mips/mips32r2@isa-override-1.d
> @@ -11,10 +11,10 @@ Disassembly of section \.text:
>  [0-9a-f]+ <[^>]*> 3c0189ab     lui     at,0x89ab
>  [0-9a-f]+ <[^>]*> 00411025     or      v0,v0,at
>  [0-9a-f]+ <[^>]*> d4820000     ldc1    \$f2,0\(a0\)
> -[0-9a-f]+ <[^>]*> 3c013ff0     lui     at,0x3ff0
> -[0-9a-f]+ <[^>]*> 44e11000     mthc1   at,\$f2
>  [0-9a-f]+ <[^>]*> 3c0189ab     lui     at,0x89ab
>  [0-9a-f]+ <[^>]*> 44811000     mtc1    at,\$f2
> +[0-9a-f]+ <[^>]*> 3c013ff0     lui     at,0x3ff0
> +[0-9a-f]+ <[^>]*> 44e11000     mthc1   at,\$f2
>  [0-9a-f]+ <[^>]*> dc820000     ldc3    \$2,0\(a0\)
>  [0-9a-f]+ <[^>]*> 340189ab     li      at,0x89ab
>  [0-9a-f]+ <[^>]*> 00010c38     0x10c38
> @@ -34,17 +34,17 @@ Disassembly of section \.text:
>  [0-9a-f]+ <[^>]*> 3c0189ab     lui     at,0x89ab
>  [0-9a-f]+ <[^>]*> 00411025     or      v0,v0,at
>  [0-9a-f]+ <[^>]*> d4820000     ldc1    \$f2,0\(a0\)
> -[0-9a-f]+ <[^>]*> 3c013ff0     lui     at,0x3ff0
> -[0-9a-f]+ <[^>]*> 44e11000     mthc1   at,\$f2
>  [0-9a-f]+ <[^>]*> 3c0189ab     lui     at,0x89ab
>  [0-9a-f]+ <[^>]*> 44811000     mtc1    at,\$f2
> +[0-9a-f]+ <[^>]*> 3c013ff0     lui     at,0x3ff0
> +[0-9a-f]+ <[^>]*> 44e11000     mthc1   at,\$f2
>  [0-9a-f]+ <[^>]*> 8c820000     lw      v0,0\(a0\)
>  [0-9a-f]+ <[^>]*> 8c830004     lw      v1,4\(a0\)
>  [0-9a-f]+ <[^>]*> 3c0189ab     lui     at,0x89ab
>  [0-9a-f]+ <[^>]*> 00411025     or      v0,v0,at
>  [0-9a-f]+ <[^>]*> d4820000     ldc1    \$f2,0\(a0\)
> -[0-9a-f]+ <[^>]*> 3c013ff0     lui     at,0x3ff0
> -[0-9a-f]+ <[^>]*> 44e11000     mthc1   at,\$f2
>  [0-9a-f]+ <[^>]*> 3c0189ab     lui     at,0x89ab
>  [0-9a-f]+ <[^>]*> 44811000     mtc1    at,\$f2
> +[0-9a-f]+ <[^>]*> 3c013ff0     lui     at,0x3ff0
> +[0-9a-f]+ <[^>]*> 44e11000     mthc1   at,\$f2
>         \.\.\.
> diff --git a/gas/testsuite/gas/mips/mips64r2@isa-override-1.d b/gas/testsuite/gas/mips/mips64r2@isa-override-1.d
> index d53fb2c..1e81c4e 100644
> --- a/gas/testsuite/gas/mips/mips64r2@isa-override-1.d
> +++ b/gas/testsuite/gas/mips/mips64r2@isa-override-1.d
> @@ -11,10 +11,10 @@ Disassembly of section \.text:
>  [0-9a-f]+ <[^>]*> 3c0189ab     lui     at,0x89ab
>  [0-9a-f]+ <[^>]*> 00411025     or      v0,v0,at
>  [0-9a-f]+ <[^>]*> d4820000     ldc1    \$f2,0\(a0\)
> -[0-9a-f]+ <[^>]*> 3c013ff0     lui     at,0x3ff0
> -[0-9a-f]+ <[^>]*> 44e11000     mthc1   at,\$f2
>  [0-9a-f]+ <[^>]*> 3c0189ab     lui     at,0x89ab
>  [0-9a-f]+ <[^>]*> 44811000     mtc1    at,\$f2
> +[0-9a-f]+ <[^>]*> 3c013ff0     lui     at,0x3ff0
> +[0-9a-f]+ <[^>]*> 44e11000     mthc1   at,\$f2
>  [0-9a-f]+ <[^>]*> dc820000     ld      v0,0\(a0\)
>  [0-9a-f]+ <[^>]*> 340189ab     li      at,0x89ab
>  [0-9a-f]+ <[^>]*> 00010c38     dsll    at,at,0x10
> @@ -34,17 +34,17 @@ Disassembly of section \.text:
>  [0-9a-f]+ <[^>]*> 3c0189ab     lui     at,0x89ab
>  [0-9a-f]+ <[^>]*> 00411025     or      v0,v0,at
>  [0-9a-f]+ <[^>]*> d4820000     ldc1    \$f2,0\(a0\)
> -[0-9a-f]+ <[^>]*> 3c013ff0     lui     at,0x3ff0
> -[0-9a-f]+ <[^>]*> 44e11000     mthc1   at,\$f2
>  [0-9a-f]+ <[^>]*> 3c0189ab     lui     at,0x89ab
>  [0-9a-f]+ <[^>]*> 44811000     mtc1    at,\$f2
> +[0-9a-f]+ <[^>]*> 3c013ff0     lui     at,0x3ff0
> +[0-9a-f]+ <[^>]*> 44e11000     mthc1   at,\$f2
>  [0-9a-f]+ <[^>]*> 8c820000     lw      v0,0\(a0\)
>  [0-9a-f]+ <[^>]*> 8c830004     lw      v1,4\(a0\)
>  [0-9a-f]+ <[^>]*> 3c0189ab     lui     at,0x89ab
>  [0-9a-f]+ <[^>]*> 00411025     or      v0,v0,at
>  [0-9a-f]+ <[^>]*> d4820000     ldc1    \$f2,0\(a0\)
> -[0-9a-f]+ <[^>]*> 3c013ff0     lui     at,0x3ff0
> -[0-9a-f]+ <[^>]*> 44e11000     mthc1   at,\$f2
>  [0-9a-f]+ <[^>]*> 3c0189ab     lui     at,0x89ab
>  [0-9a-f]+ <[^>]*> 44811000     mtc1    at,\$f2
> +[0-9a-f]+ <[^>]*> 3c013ff0     lui     at,0x3ff0
> +[0-9a-f]+ <[^>]*> 44e11000     mthc1   at,\$f2
>         \.\.\.
> --
> 2.7.4
>



More information about the Binutils mailing list