2012-06-21 12 views
5

PowerPCアセンブリを初めて使用しています。私はMPC8245(はい、古い学校)で働いています。これは603eファミリプロセッサです。PowerPCアセンブリのロード即時

即時の16ビット値が「符号なし」であるロード即値命令を作成する方法を知りたいと思います。

例:リチウムr3,0xFC10

GCCクロスコンパイラ、4.4.5、I値が一定で署名されていないとして、この命令を使用できません使用しています。

はい、私はマイナス2の補数を使うことができましたが、これはコードの読み込みと文書化をより困難にします。デバイスレジスタ用のビットフィールドをロードするとき、命令内の正確なビットフィールドを読み込む方がはるかに簡単です。

+0

-1008 0xFC10と同じ2の補数表現を持つ。おそらくあなたは(0xfc10-0x10000)と書くことができますか? –

+0

または手動で0xFFFFFC10に符号拡張しますか? –

+0

@tc - 興味深い。 li命令は16ビット値のみを受け入れますが、li r3,0xFFFFFC10は法的命令です。 – KeithSmith

答えて

10

liは、addi命令として実際に変換される擬似オペコードです。 rAフィールドは、それが代わりr0のリテラル0を指定する場合には、0である場合

addi rD, rA, SIMMは、rDに結果を確定する、以外rAに署名した即時SIMMを加算します。 li rD, SIMMは実際にはaddi rD, 0, SIMMです。

これは、値を00x7fff0xffff80000xffffffffからローディングするのに適していますが、それ以外の値はロードできません。

即値ビット演算オペコード(oriなど)は、16ビットの即値フィールドを符号なしの値として解釈します。ただし、「はリテラルを意味します。0」の動作はaddiではありません。

あなたはレジスタに0xfc10の定数をロードするために2つの命令を使用する必要があります:(あなたは、任意の32ビット定数の上半分をロードしているかのように、またはlisliを使用して0とレジスタにロードして、または、符号なし16ビット値でoriとします。

これはgccは状況下でまったく同じものです:

$ cat test.c 
unsigned int test(void) 
{ 
    return 0xfc10; 
} 
$ gcc -O2 -c test.c 
$ objdump -d test.o 

test.o:  file format elf32-powerpc 

Disassembly of section .text: 

00000000 <test>: 
    0: 38 60 00 00  li  r3,0 
    4: 60 63 fc 10  ori  r3,r3,64528 
    8: 4e 80 00 20  blr 
    c: 60 00 00 00  nop 
$ 

私は GNUアセンブラは自動的にシングルからそのような値をロードする2つの命令を生成する任意の方法を持っているとは思いませんPowerPC用にアセンブルするときのソース命令。しかし、あなたは、一定の(符号なし)ハイとローの16ビットの半分、例えばを抽出するために@h@lサフィックスを使用することができます。

lis r3, [email protected]   /* => li r3, 0x1234  */ 
ori r3, r3, [email protected]  /* => ori r3, r3, 0x5678 */ 

あなたは任意の定数ロードするための独自のマクロを記述するためにこれを使用することができます。.. 。

$ cat test2.s 
     .macro load_const rD, const 
     .if (\const >= -0x8000) && (\const <= 0x7fff) 
     li  \rD, \const 
     .else 
     lis  \rD, \[email protected] 
     ori  \rD, \rD, \[email protected] 
     .endif 
     .endm 

     load_const r3, 0 
     load_const r4, 1 
     load_const r5, -1 
     load_const r6, 0x7fff 
     load_const r7, 0x8000 
     load_const r8, -32767 
     load_const r9, -32768 
     load_const r10, -32769 
     load_const r11, 0xfc10 

$ as -mregnames -o test2.o test2.s 
$ objdump -d test2.o 

test2.o:  file format elf32-powerpc 

Disassembly of section .text: 

00000000 <.text>: 
    0: 38 60 00 00  li  r3,0 
    4: 38 80 00 01  li  r4,1 
    8: 38 a0 ff ff  li  r5,-1 
    c: 38 c0 7f ff  li  r6,32767 
    10: 3c e0 00 00  lis  r7,0 
    14: 60 e7 80 00  ori  r7,r7,32768 
    18: 39 00 80 01  li  r8,-32767 
    1c: 39 20 80 00  li  r9,-32768 
    20: 3d 40 ff ff  lis  r10,-1 
    24: 61 4a 7f ff  ori  r10,r10,32767 
    28: 3d 60 00 00  lis  r11,0 
    2c: 61 6b fc 10  ori  r11,r11,64528 
$ 
+0

マット - 徹底的な答えをありがとう。私が使っているビルド環境には 'lwi'マクロがあります。 'li'で符号なしの値を使用するときにgccによって報告されるエラーは、前述のように「エラー:オペランドが範囲外です(0x00008000は0xffff8000と0x00007fffの間にありません)」です。 – KeithSmith

0

あなたはまた、オペレータoriを使用することによって直ちに符号なしの16ビットをロードしますが、前にレジスタをクリアしてください可能性があり:

xor r3, r3, r3 
ori r3, r3, 0xFC10 
関連する問題