新版FM音源プログラム (18)

アセンブリ言語によるスロット (オペレータ) 計算プログラムでは、ARMv6-M (Cortex-M0) の 16 ビット Thumb 命令を主に使うこととし、ARMv7-M (Cortex-M3/M4) に対しては一部を 32 ビット Thumb2 命令で記述することにより効率化しています。
以下に、その「一部分」を示します。

#if defined(__thumb2__) // ARMv7-M (Cortex-M3/M4)
    "  ands    r3, r3,r4,lsr #8    \n\t"
#else                   // ARMv6-M (Cortex-M0)
    "  lsrs    r4, r4,#8           \n\t"
    "  ands    r3, r3,r4           \n\t"
#endif
    "  ldrsh   r3,[r5,r3]          \n\t"

これは、フェーズ・アキュムレータ (ph_acc) の値からシフトおよび AND によってサイン波テーブルアクセスのためのバイト・オフセットを切り出す部分です。
Thumb 命令の範囲では、シフト命令 lsrs と AND 命令 ands の 2 命令必要ですが、Thumb2 命令では ands 命令の「シフト付きオペランド」でシフト命令の役割を果たすことができます。

#if defined(__thumb2__)  // ARMv7-M (Cortex-M3/M4)
    "  ldrsh   r5,[r0,%[op_out]]   \n\t"
#else                    // ARMv6-M (Cortex-M0)
    "  ldrh    r5,[r0,%[op_out]]   \n\t"
    "  sxth    r5, r5              \n\t"
#endif

これは、オペレータ出力 (op_out) を読み出している部分ですが、Thumb 命令には符号付きハーフワード (int16_t) 型のデータを 32 ビットに符号拡張して、定数オフセット・アドレッシングで読み出す ldrsh 命令がないため、まず、1 命令目で、「ゼロ拡張」である ldrh 命令で int16_t データを読み出し、2 命令目の sxth で 16 ビットデータを 32 ビットに符号拡張しています。
Thumb2 命令には定数オフセットの ldrsh 命令があるので、(命令長は 32 ビットになりますが) それを使います。
ここは、「レジスタ・オフセット形式」の ldrsh 命令は Thumb にもあるので、

    "  movs    r5,%[op_out]       \n\t"
    "  ldrsh   r5,[r0,r5]         \n\t"

としても (レジスタを 1 個使ってしまいますが) 実現できます。

#if defined(__thumb2__) // ARMv7-M (Cortex-M3/M4)
    "  mla     r4, r4, r5, r2           \n\t"
#else                   // ARMv6-M (Cortex-M0)
    "  muls    r4, r5,r4                \n\t"
    "  adds    r4, r4,r2                \n\t"
#endif

これはキャリア・オペレータのフェーズ・アキュムレータの計算で、モジュレータ側からのモジュレーションを掛けている部分です。
r2 には (ph_acc + ph_inc) の値、r4 にはモジュレータの op_out の値、R5 にはモジュレーションありかなしかを決める mod_mul の値が入っています。

      r4 = (r4 * r5) + r2
         = (op_out * mod_mul) + (ph_acc + ph_inc)

を計算しています。
Thumb 命令では「積和命令」がないので、乗算の muls 命令と、加算の adds 命令の 2 命令で実現しています。
Thumb2 命令では「Multiply Accumulate 」命令ひとつ

      mla  rd, rn, rm, ra

      rd = (rn * rm) + ra 

という計算が実行できます。
Cortex-M3 の場合には、mla 命令の実行サイクル数は 2 で、Thumb 命令の muls / adds の 2 命令バージョンと変わりありませんが、Cortex-M4 の場合には実行サイクル数 1 となって、少し得をします。