> case SYMBOL_SMALL_GOTTPREL: > { > - rtx tmp_reg = gen_reg_rtx (Pmode); > + /* In ILP32, the mode of dest can be either SImode or DImode, > + while the got entry is always of SImode size. The mode of > + dest depends on how dest is used: if dest is assigned to a > + pointer (e.g. in the memory), it has SImode; it may have > + DImode if dest is dereferenced to access the memeory. > + This is why we have to handle three different tlsie_small > + patterns here (two patterns for ILP32). */ > + enum machine_mode mode = GET_MODE (dest); > + rtx tmp_reg = gen_reg_rtx (mode); > rtx tp = aarch64_load_tp (NULL); > - emit_insn (gen_tlsie_small (tmp_reg, imm)); > - emit_insn (gen_rtx_SET (Pmode, dest, gen_rtx_PLUS (Pmode, tp, > tmp_reg))); > + > + if (mode == ptr_mode) > + { > + if (mode == DImode) > + emit_insn (gen_tlsie_small_di (tmp_reg, imm)); > + else > + { > + emit_insn (gen_tlsie_small_si (tmp_reg, imm)); > + tp = gen_lowpart (mode, tp); > + } > + } > + else > + { > + gcc_assert (mode == Pmode); > + emit_insn (gen_tlsie_small_sidi (tmp_reg, imm)); > + }
Andrew, do you recall the circumstance that trigger the mode == SImode code path through the above code? I've been trying to trigger this while working on the equivalent tiny address mode code... with no success. /Marcus