Самый эффективный способ упаковать sh всех регистров в стек в ARM64 - PullRequest
1 голос
/ 09 июля 2020

Я ищу способ передать sh все регистры в стек в arm64 для ISR. Мой текущий код выглядит следующим образом:

    stp x0, x1, [sp, #-16]!
    stp x2, x3, [sp, #-16]!
    stp x4, x5, [sp, #-16]!
    stp x6, x7, [sp, #-16]!
    stp x8, x9, [sp, #-16]!
    stp x10, x11, [sp, #-16]!
    stp x12, x13, [sp, #-16]!
    stp x14, x15, [sp, #-16]!
    stp x16, x17, [sp, #-16]!
    stp x18, x19, [sp, #-16]!
    stp x20, x21, [sp, #-16]!
    stp x22, x23, [sp, #-16]!
    stp x24, x25, [sp, #-16]!
    stp x26, x27, [sp, #-16]!
    stp x28, x29, [sp, #-16]!
    str x30, [sp, #-16]!

    stp q0, q1, [sp, #-32]!
    stp q2, q3, [sp, #-32]!
    stp q4, q5, [sp, #-32]!
    stp q6, q7, [sp, #-32]!
    stp q8, q9, [sp, #-32]!
    stp q10, q11, [sp, #-32]!
    stp q12, q13, [sp, #-32]!
    stp q14, q15, [sp, #-32]!
    stp q16, q17, [sp, #-32]!
    stp q18, q19, [sp, #-32]!
    stp q20, q21, [sp, #-32]!
    stp q22, q23, [sp, #-32]!
    stp q24, q25, [sp, #-32]!
    stp q26, q27, [sp, #-32]!
    stp q28, q29, [sp, #-32]!
    stp q30, q31, [sp, #-32]!

    mrs x0, FPCR
    mrs x1, FPSR
    str x0, [sp, #-16]!
    str x1, [sp, #-16]!

    bl  vector_irq

    ldr x0,  [sp, #16]!
    ldr x1,  [sp, #16]!
    msr FPCR, x0
    msr FPSR, x1

    ldp q30, q31, [sp, #32]!
    ldp q28, q29, [sp, #32]!
    ldp q26, q27, [sp, #32]!
    ldp q24, q25, [sp, #32]!
    ldp q22, q23, [sp, #32]!
    ldp q20, q21, [sp, #32]!
    ldp q18, q19, [sp, #32]!
    ldp q16, q17, [sp, #32]!
    ldp q14, q15, [sp, #32]!
    ldp q12, q13, [sp, #32]!
    ldp q10, q11, [sp, #32]!
    ldp q8, q9, [sp, #32]!
    ldp q6, q7, [sp, #32]!
    ldp q4, q5, [sp, #32]!
    ldp q2, q3, [sp, #32]!
    ldp q0, q1, [sp, #32]!

    ldr x30, [sp, #16]!
    ldp x28, x29, [sp, #16]!
    ldp x26, x27, [sp, #16]!
    ldp x24, x25, [sp, #16]!
    ldp x22, x23, [sp, #16]!
    ldp x20, x21, [sp, #16]!
    ldp x18, x19, [sp, #16]!
    ldp x16, x17, [sp, #16]!
    ldp x14, x15, [sp, #16]!
    ldp x12, x13, [sp, #16]!
    ldp x10, x11, [sp, #16]!
    ldp x8, x9, [sp, #16]!
    ldp x6, x7, [sp, #16]!
    ldp x4, x5, [sp, #16]!
    ldp x2, x3, [sp, #16]!
    ldp x0, x1, [sp, #16]!

    eret

(т.е. сначала pu sh все регистры общего назначения, затем pu sh все регистры SIMD FP, переход к правильному вектору и затем все обратно)

Есть способ сделать это более эффективно? Это прерывание запускается очень часто, и любое увеличение производительности приятно иметь.

1 Ответ

3 голосов
/ 09 июля 2020

Я предполагаю, что все регистры действительно нужно сохранить, как уже упоминалось в комментариях.

С регистрами общего назначения не более двух могут быть записаны или загружены в память в В то же время инструкции для этого просто нет. С регистрами SIMD все немного иначе: с помощью инструкции

ST4 { V0.2D, V1.2D, V2.2D, V3.2D }, [SP], #64

можно записать четыре последовательных регистра SIMD одновременно. Это приводит к чередованию значений регистров, прежде чем они будут помещены в стек. Однако это не должно быть проблемой, если они перезагружаются таким же образом (с использованием LD4) и пока к ним не обращаются (в противном случае вам нужно выяснить, где оказались ваши значения). Это уменьшает размер кода, а также может ускорить его (см. Мой вопрос здесь ). Это заменит соответствующую часть в вашем коде

    stp q0, q1, [sp, #-32]!
    // ...
    stp q30, q31, [sp, #-32]!

четырьмя строками

    st4 {  v0.2d,  v1.2d,  v2.2d,  v3.2d }, [sp], #64
    st4 {  v4.2d,  v5.2d,  v6.2d,  v7.2d }, [sp], #64
    st4 {  v8.2d,  v9.2d, v10.2d, v11.2d }, [sp], #64
    st4 { v12.2d, v13.2d, v14.2d, v15.2d }, [sp], #64

и аналогично LD4. Обратите внимание, что ST4 поддерживает только постиндекс, в то время как вы всегда использовали предварительный индекс. Проще всего это везде поменять.

...