Как избежать запланированного insn bee в слот задержки - PullRequest
2 голосов
/ 10 февраля 2010

Я пытаюсь пропатчить gcc, чтобы после fdivd регистр назначения хранится в стеке, то есть:

fdivd% f0,% f2,% f4; => становится fdivd% f0,% f2,% f4; стандартный% f4, [% fp + ...]

Я генерирую RTL для divdf3 с использованием последовательности (emit_insn, DONE) в шаблон define_expand (см. ниже).

В фазе вывода ассемблера я использую define_insn и пишу out "fdivd \ t %% 1, %% 2, %% 0; std %% 0, %% 3" в качестве строки выражения.

Сгенерированный код вроде бы в порядке. Тем не менее:

Мой вопрос:

Как я могу пометить шаблон так, чтобы не был запланирован в слот задержки ? Как можно указать, что на выходе будет 2 инструкции а намекнуть на это планировщику? Является ли атрибут (set_attr "length" "2") в define_insn divdf3_store (ниже) уже достаточно?

- Привет Конрад

-------------- changed sparc.md -------------------------
;;;;;;;;;;;;;;;;;; handle divdf3 ;;;;;;;;;;;;;;;;
(define_expand "divdf3"
  [(parallel [(set (match_operand:DF 0 "register_operand" "=e")
                      (div:DF (match_operand:DF 1 "register_operand" "e")
                (match_operand:DF 2 "register_operand" "e")))
          (clobber (match_scratch:SI 3 ""))])]
  "TARGET_FPU"
  "{
      output_divdf3_emit (operands[0], operands[1], operands[2], operands[3]);
      DONE;
    }")

(define_insn "divdf3_store"
  [(set (match_operand:DF 0 "register_operand" "=e")
                      (div:DF (match_operand:DF 1 "register_operand" "e")
                (match_operand:DF 2 "register_operand" "e")))
          (clobber (match_operand:DF 3 "memory_operand" ""  ))]
  "TARGET_FPU && TARGET_STORE_AFTER_DIVSQRT"
   {
       return output_divdf3 (operands[0], operands[1], operands[2], operands[3]);
   }
   [(set_attr "type" "fpdivd")
   (set_attr "fptype" "double")
   (set_attr "length" "2")])

(define_insn "divdf3_nostore"
  [(set (match_operand:DF 0 "register_operand" "=e")
    (div:DF (match_operand:DF 1 "register_operand" "e")
        (match_operand:DF 2 "register_operand" "e")))]
  "TARGET_FPU && (!TARGET_STORE_AFTER_DIVSQRT)"
  "fdivd\t%1, %2, %0"
  [(set_attr "type" "fpdivd")
   (set_attr "fptype" "double")])



-------------- changed sparc.c -------------------------

/**************************** handle fdivd ****************************/
char *
output_divdf3 (rtx op0, rtx op1, rtx dest, rtx scratch)
{
  static char string[128];
  if (debug_patch_divsqrt) {
    fprintf(stderr, "debug_patch_divsqrt:\n");
    debug_rtx(op0);
    debug_rtx(op1);
    debug_rtx(dest);
    fprintf(stderr, "scratch: 0x%x\n",(int)scratch);
  }
  sprintf(string,"fdivd\t%%1, %%2, %%0; std %%0, %%3 !!!");
  return string;
}

void
output_divdf3_emit (rtx dest, rtx op0, rtx op1, rtx scratch)
{
  rtx slot0, div, divsave;

  if (debug_patch_divsqrt) {
    fprintf(stderr, "output_divdf3_emit:\n");
    debug_rtx(op0);
    debug_rtx(op1);
    debug_rtx(dest);
    fprintf(stderr, "scratch: 0x%x\n",(int)scratch);
  }

  div = gen_rtx_SET (VOIDmode,
             dest,
             gen_rtx_DIV (DFmode,
                  op0,
                  op1));

  if (TARGET_STORE_AFTER_DIVSQRT) {
    slot0 = assign_stack_local (DFmode, 8, 8);
    divsave = gen_rtx_SET (VOIDmode, slot0, dest);
    emit_insn(divsave);
    emit_insn (gen_rtx_PARALLEL(VOIDmode,
                gen_rtvec (2,
                       div,
                       gen_rtx_CLOBBER (SImode,
                                slot0))));
  } else {
    emit_insn(div);
  }
} 

1 Ответ

1 голос
/ 12 февраля 2010

Я второй лаурины. Для такого точного вопроса, gcc@gcc.gnu.org будет очень полезен.

...