在 2024/1/4 下午5:05, chenglulu 写道:

在 2024/1/4 下午12:05, Xi Ruoyao 写道:
On Thu, 2024-01-04 at 11:58 +0800, chenglulu wrote:
在 2024/1/4 上午11:51, Xi Ruoyao 写道:
On Wed, 2023-12-27 at 16:46 +0800, Lulu Cheng wrote:
+(define_insn "movdi_pcrel64"
+ [(set (match_operand:DI 0 "register_operand" "=&r")
+       (match_operand:DI 1 "symbolic_pcrel64_operand"))
+  (unspec:DI [(const_int 0)]
+    UNSPEC_MOV_PCREL64)
+  (use (reg:DI T3_REGNUM))
+  (clobber (reg:DI T3_REGNUM))]
It's better not to hard code $t3 here.  We can write

[(set (match_operand:DI 0 "register_operand" "=r")
         (match_operand:DI 1 "symbolic_pcrel64_operand"))
    (clobber (match_operand:DI 2 "register_operand "=&r"))]

And use

     gen_movdi_pcrel64 (operands[0], operands[1], gen_reg_rtx(DImode))

in expand.

I tried using (clobber (match_scratch)) when implementing it, but it
didn't work.
I tried match_scratch a few times as well in my previous hacks but never
succeeded :(.

In the function loongarch_output_mi_thunk, the address of the symbol .LTHUNK0

will be obtained, but at this time it is no longer possible to apply for temporary variables.

So there will be ICE here

See attachment for test cases.

The compilation command is as follows:

$ ./gcc/cc1plus -fpreprocessed example.ii -quiet -dumpbase example.cc -dumpbase-ext .cc -mexplicit-relocs=none -mno-relax -mabi=lp64d -march=loongarch64 -mfpu=64 -msimd=lasx -mcmodel=extreme -mtune=loongarch64 -g3 -O2 -Wno-int-conversion -Wno-implicit-int -Wno-implicit-function-declaration -Wno-incompatible-pointer-types -std=c++98 -version -o example.s



I have now made the following modifications and are testing for correctness:

@@ -7450,12 +7450,22 @@ loongarch_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,

      allowed, otherwise load the address into a register first.  */
   if (use_sibcall_p)
     {
-      insn = emit_call_insn (gen_sibcall_internal (fnaddr, const0_rtx));
+      if (TARGET_CMODEL_EXTREME)
+       {
+         emit_insn (gen_movdi_pcrel64 (temp1, fnaddr, temp2));
+         insn = emit_call_insn (gen_sibcall_internal (temp1, const0_rtx));
+       }
+      else
+       insn = emit_call_insn (gen_sibcall_internal (fnaddr, const0_rtx));
       SIBLING_CALL_P (insn) = 1;
     }
   else
     {
-      loongarch_emit_move (temp1, fnaddr);
+      if (TARGET_CMODEL_EXTREME)
+       emit_insn (gen_movdi_pcrel64 (temp1, fnaddr, temp2));
+      else
+       loongarch_emit_move (temp1, fnaddr);
+
       emit_jump_insn (gen_indirect_jump (temp1));
     }

Reply via email to