@@ -22749,6 +22749,48 @@ current_fentry_section (const char **name)
2274922749 return true;
2275022750}
2275122751
22752+ /* Return a caller-saved register which isn't live or a callee-saved
22753+ register which has been saved on stack in the prologue at entry for
22754+ profile. */
22755+
22756+ static int
22757+ x86_64_select_profile_regnum (bool r11_ok ATTRIBUTE_UNUSED)
22758+ {
22759+ /* Use %r10 if the profiler is emitted before the prologue or it isn't
22760+ used by DRAP. */
22761+ if (ix86_profile_before_prologue ()
22762+ || !crtl->drap_reg
22763+ || REGNO (crtl->drap_reg) != R10_REG)
22764+ return R10_REG;
22765+
22766+ /* The profiler is emitted after the prologue. If there is a
22767+ caller-saved register which isn't live or a callee-saved
22768+ register saved on stack in the prologue, use it. */
22769+
22770+ bitmap reg_live = df_get_live_out (ENTRY_BLOCK_PTR_FOR_FN (cfun));
22771+
22772+ int i;
22773+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
22774+ if (GENERAL_REGNO_P (i)
22775+ && i != R10_REG
22776+ #ifdef NO_PROFILE_COUNTERS
22777+ && (r11_ok || i != R11_REG)
22778+ #else
22779+ && i != R11_REG
22780+ #endif
22781+ && TEST_HARD_REG_BIT (accessible_reg_set, i)
22782+ && (ix86_save_reg (i, true, true)
22783+ || (call_used_regs[i]
22784+ && !fixed_regs[i]
22785+ && !REGNO_REG_SET_P (reg_live, i))))
22786+ return i;
22787+
22788+ sorry ("no register available for profiling %<-mcmodel=large%s%>",
22789+ ix86_cmodel == CM_LARGE_PIC ? " -fPIC" : "");
22790+
22791+ return INVALID_REGNUM;
22792+ }
22793+
2275222794/* Output assembler code to FILE to increment profiler label # LABELNO
2275322795 for profiling a function entry. */
2275422796void
@@ -22783,42 +22825,61 @@ x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
2278322825 fprintf (file, "\tleaq\t%sP%d(%%rip), %%r11\n", LPREFIX, labelno);
2278422826#endif
2278522827
22828+ int scratch;
22829+ const char *reg;
22830+ char legacy_reg[4] = { 0 };
22831+
2278622832 if (!TARGET_PECOFF)
2278722833 {
2278822834 switch (ix86_cmodel)
2278922835 {
2279022836 case CM_LARGE:
22791- /* NB: R10 is caller-saved. Although it can be used as a
22792- static chain register, it is preserved when calling
22793- mcount for nested functions. */
22837+ scratch = x86_64_select_profile_regnum (true);
22838+ reg = hi_reg_name[scratch];
22839+ if (LEGACY_INT_REGNO_P (scratch))
22840+ {
22841+ legacy_reg[0] = 'r';
22842+ legacy_reg[1] = reg[0];
22843+ legacy_reg[2] = reg[1];
22844+ reg = legacy_reg;
22845+ }
2279422846 if (ASSEMBLER_DIALECT == ASM_INTEL)
22795- fprintf (file, "1:\tmovabs\tr10 , OFFSET FLAT:%s\n"
22796- "\tcall\tr10 \n", mcount_name);
22847+ fprintf (file, "1:\tmovabs\t%s , OFFSET FLAT:%s\n"
22848+ "\tcall\t%s \n", reg, mcount_name, reg );
2279722849 else
22798- fprintf (file, "1:\tmovabsq\t$%s, %%r10 \n\tcall\t*%%r10 \n",
22799- mcount_name);
22850+ fprintf (file, "1:\tmovabsq\t$%s, %%%s \n\tcall\t*%%%s \n",
22851+ mcount_name, reg, reg );
2280022852 break;
2280122853 case CM_LARGE_PIC:
2280222854#ifdef NO_PROFILE_COUNTERS
22855+ scratch = x86_64_select_profile_regnum (false);
22856+ reg = hi_reg_name[scratch];
22857+ if (LEGACY_INT_REGNO_P (scratch))
22858+ {
22859+ legacy_reg[0] = 'r';
22860+ legacy_reg[1] = reg[0];
22861+ legacy_reg[2] = reg[1];
22862+ reg = legacy_reg;
22863+ }
2280322864 if (ASSEMBLER_DIALECT == ASM_INTEL)
2280422865 {
2280522866 fprintf (file, "1:movabs\tr11, "
2280622867 "OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-1b\n");
22807- fprintf (file, "\tlea\tr10 , 1b[rip]\n");
22808- fprintf (file, "\tadd\tr10 , r11\n");
22868+ fprintf (file, "\tlea\t%s , 1b[rip]\n", reg );
22869+ fprintf (file, "\tadd\t%s , r11\n", reg );
2280922870 fprintf (file, "\tmovabs\tr11, OFFSET FLAT:%s@PLTOFF\n",
2281022871 mcount_name);
22811- fprintf (file, "\tadd\tr10 , r11\n");
22812- fprintf (file, "\tcall\tr10 \n");
22872+ fprintf (file, "\tadd\t%s , r11\n", reg );
22873+ fprintf (file, "\tcall\t%s \n", reg );
2281322874 break;
2281422875 }
2281522876 fprintf (file,
2281622877 "1:\tmovabsq\t$_GLOBAL_OFFSET_TABLE_-1b, %%r11\n");
22817- fprintf (file, "\tleaq\t1b(%%rip), %%r10 \n");
22818- fprintf (file, "\taddq\t%%r11, %%r10 \n");
22878+ fprintf (file, "\tleaq\t1b(%%rip), %%%s \n", reg );
22879+ fprintf (file, "\taddq\t%%r11, %%%s \n", reg );
2281922880 fprintf (file, "\tmovabsq\t$%s@PLTOFF, %%r11\n", mcount_name);
22820- fprintf (file, "\taddq\t%%r11, %%r10 \n");
22821- fprintf (file, "\tcall\t*%%r10 \n");
22881+ fprintf (file, "\taddq\t%%r11, %%%s \n", reg );
22882+ fprintf (file, "\tcall\t*%%%s \n", reg );
2282222883#else
2282322884 sorry ("profiling %<-mcmodel=large%> with PIC is not supported");
2282422885#endif
0 commit comments