2011-06-20 9 views
2

私はiPhone/iPadプロジェクトで作業しており、一部の(すべてではない)算術演算中にステータスレジスタを更新したいと考えています。デフォルトでは、Xcodeは「Thumbのためのコンパイル」を使用しています。変更したくありません。Apple ASとARM/Thumb ADDS命令

次のGCCインラインアセンブリコードはARMではうまく動作しますが、Thumb: '命令はThumb16モードではサポートされていません - r6、r4、r5を追加してコンパイルエラーが発生します。問題はステータスレジスタの更新にあります。 (私はまた、movcsstrcsを変更する必要があることを認識しています)。

Thumbには、CPSRにオーバーフロー(V)またはキャリー(C)を設定するADD命令がありますか?そうでない場合は、オーバーフローやキャリーをテストするためのThumb固有のアセンブリレベルの回避策がありますか?

ジェフ

uint32_t result, a, b; 
int no_carry = 1; 
... 

__asm__ 
(
    "ldr r4, %[xa] ;" // R4 = a 
    "ldr r5, %[xb] ;" // R5 = b 
    "adds r6, r4, r5 ;" // R6 = R4 + R5, set status 
    "movcs r4, #0  ;" // set overflow (if carry set) 
    "strcs r4, %[xc] ;" // store it (if carry set) 
    "str r6, %[xr] ;" // result = R6 
    : [xr] "=m" (result), [xc] "=m" (no_carry) 
    : [xa] "m" (a), [xb] "m" (b) 
    : "r4", "r5", "r6" 
); 

... 

EDIT:レジスタもARM ABI at Application Binary Interface (ABI) for the ARM Architectureを利用するために周りに移動する必要があります。

+0

「コンパイル用のThumb」ビルド設定を見ましたか?申し訳ありませんが、お聞きしました。 –

答えて

0

Thumb-16 Quick Reference Guideによれば、ADDS命令が利用可能である必要があります。これはアセンブラのバグ(@dwelchで確認されたように)のようです。

私は、アセンブラディレクティブを使用して事前にエンコードされた命令を発行することで回避できることがわかりました。たとえば:

__asm__ 
(
    "ldr r0, %[xa] ;" // R0 = a 
    "ldr r1, %[xb] ;" // R1 = b 
    ".inst.w 0x1809 ;" // Issue 'adds r1, r1, r0' 
    ... 
); 

私はadds r2, r2, r1を望んでいた場合、コードはそうで.inst.w 0x1852を放出し、そして必要があります。

__asm__ 
(
    "ldr r0, %[xa] ;" // R0 = a 
    "ldr r1, %[xb] ;" // R1 = b 
    "adds r1, r1, r0 ;" // R1 = a + b 
    ... 
); 

を使用して実現されるだろう。

EDIT:最近Binutilsメーリングリストのarm thumb2 ldr.w syntax?のコードが更新されました。

4

私はXCodeとAppleのツールチェーンにはあまりよく慣れていませんが、古いUAL形式のアセンブリを期待している可能性があります。 ADDのThumb-16エンコーディングは常にフラグ(レジスタR0〜R7)を設定しますが、UAL前のアセンブリではSがニーモニックに追加されませんでした。 (ほとんどの算術演算ではThumb-16のフラグが更新されるため、Sが暗黙に記述されています)。したがって、アセンブリブロックの先頭に.syntax_unifiedを追加するか、単純なADDニーモニックを使用してください。

ただし、コードに別の問題があります。 Thumb-16は条件付き命令をサポートせず、条件付き分岐のみをサポートします。したがって、ブランチを使用してコードをやり直すか、ADC/SBCを使用する必要があります。

上記のすべては、元のThumb ISA(別名Thumb-16)にのみ適用されることに注意してください。 Thumb-2(別名Thumb-32)は、高レジスタと条件付き命令を使用するなど、ARMが実行できるものを(ほとんど)実行できますが、ARMv6ターゲットでは使用できません(おそらくXCodeのデフォルトです)。

+0

"しかし、あなたのコードに別の問題があります..." GASはあまりにも早く(ADDSの後で)不平を言った。ありがとう - 固定。 – jww

+0

"ADDのThumb-16エンコーディングは常にフラグを設定します" - これは興味深いものです。次のリンクによれば、ADDSはThumb16でサポートされています。おそらくこれはAppleのGASのバグです。 http://infocenter.arm.com/help/topic/com.arm.doc.qrc0006e/QRC0006_UAL16.pdfを参照してください。 – jww

+1

すべての現在のARMドキュメントでは、Sが明示的に指定されたUAL構文を使用します。 「ARMアーキテクチャリファレンスマニュアル」のレガシー命令ニーモニックを参照してください。 –

4

Igorは ".syntax_unified"を提案しました。しかし、少なくともbinutils 2.22の場合、コマンドは ".sytax unified"です。次の例はここでうまくコンパイルされます:

.align 4 
.code 16 
.syntax unified 

adds r0,r0,r2 
adc r1,r1,r3