忍者ブログ

なんだか

知らないほうが幸せかもしれない

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

h8sxのmovmdの制限をgccで回避する

H8SXのブロック転送命令における制限事項というのがあります。

下のようなコードの場合は

00cc 01016976 mov.l @(4,er7),er6
00d0 01006975 mov.l @er7,er5
00d4 7BB4     movmd.l
00d6 01580506 mov.w @er5,@er6

メモリからer5に転送したあとに、movmdを実行するのではなく

00cc 01016976 mov.l   @(4,er7),er6
00d0 01006975 mov.l   @er7,er5
00d4 0000     nop
00d6 7BB4     movmd.l
00d8 01580506 mov.w   @er5,@er6

nopとかの命令を挿入しないとおかしな動作をしますよという事です。

gccには、こういう時に便利に使えるpeephole2という機能があります。
どういう機能かというと特定できる命令のパターンの組み合わせを登録しておくと
その命令のパターンの組み合わせを見つけた時に別の命令の組み合わせに変更できるのです。
(他にも、ある命令をarchに合わせて分解するようなことも出来るのです。)
命令の記述にはmd形式という形で表現されています。

movmd-movsd.patch

この中は覗かないほうがいいかもしれない。

peephole2は最適化オプションが1以上でないと機能しないので、ご注意を


拍手[0回]

PR

h8300-elfのgccを作ろうとしたら、続き

ターゲットのコンパイルオプションに-fomit-frame-pointerをつけて
やってみたら、またもや、ビルドがコケた。

../../../../../../gcc-4.7.2/libstdc++-v3/libsupc++/pmem_type_info.cc:47:1: エラー: 認識できない命令:
(insn 96 9 97 2 (parallel [
            (set/f (mem:SI (plus:SI (reg/f:SI 7 sp)
                        (const_int -4 [0xfffffffffffffffc])) [0 S4 A32])
                (reg:SI 5 r5))
            (set/f (mem:SI (plus:SI (reg/f:SI 7 sp)
                        (const_int -8 [0xfffffffffffffff8])) [0 S4 A32])
                (reg:SI 6 r6))
            (set/f (reg/f:SI 7 sp)
                (plus:SI (reg/f:SI 7 sp)
                    (const_int -8 [0xfffffffffffffff8])))
        ]) ../../../../../../gcc-4.7.2/libstdc++-v3/libsupc++/pmem_type_info.cc:37 -1
     (expr_list:REG_DEAD (reg:SI 6 r6)
        (expr_list:REG_DEAD (reg:SI 5 r5)
            (nil))))
../../../../../../gcc-4.7.2/libstdc++-v3/libsupc++/pmem_type_info.cc:47:1: コンパイラ内部エラー: extract_insn 内、位置 recog.c:2123
完全なバグ報告を送って下さい。
適切ならば前処理後のソースをつけてください。
<http://gcc.gnu.org/bugs.html> を見れば方法が書いてあります。

バグ報告してね、って書いてあるけど、ここは自力で何とかしてみましょう。
スタックにレジスタの退避をしてるようなので

(define_insn "*stm_h8300s"
  [(set (mem:SI (plus:SI (reg:SI SP_REG)
                         (const_int -4)))
        (reg:SI 5))
   (set (mem:SI (plus:SI (reg:SI SP_REG)
                         (const_int -8)))
        (reg:SI 6))
   (set (reg:SI SP_REG)
        (plus:SI (reg:SI SP_REG)
                 (const_int -8)))]
  "TARGET_H8300S"
  "mov.l\ter5,@-er7\n\tmov.l\ter6,@-er7\t!gcc push bug"
  [(set_attr "cc" "none")
   (set_attr "length" "4")])

これをgcc/config/h8300/h8300.mdにスタック操作している場所に突っ込んでみました。
これで合ってるのかはわかりませんが、アセブンルリストを眺めた限りでは大丈夫そうでした。
(この修正は前に作ったものなのです。)

と思って、よくよくソースを見直してたら、間違いらしきところを見つけました。

gcc/config/h8300/h8300.c
--- h8300.c.push_bug    2012-08-06 23:34:27.000000000 +0900
+++ h8300.c    2012-12-16 21:55:57.345816636 +0900
@@ -817,15 +817,14 @@ h8300_expand_prologue (void)
       if (TARGET_H8300S)
         {
           /* See how many registers we can push at the same time.  */
-          if ((!TARGET_H8300SX || (regno & 3) == 0)
+          if ((TARGET_H8300SX || (regno & 3) == 0)
           && ((saved_regs >> regno) & 0x0f) == 0x0f)
         n_regs = 4;
 
-          else if ((!TARGET_H8300SX || (regno & 3) == 0)
+          else if ((TARGET_H8300SX || (regno & 3) == 0)
                && ((saved_regs >> regno) & 0x07) == 0x07)
         n_regs = 3;
-
-          else if ((!TARGET_H8300SX || (regno & 1) == 0)
+          else if ((TARGET_H8300SX || (regno & 1) == 0)
                && ((saved_regs >> regno) & 0x03) == 0x03)
         n_regs = 2;
         }

!TARGET_8300SXの!が余計だったという。逆のことをやってるところでは!はついていないので大丈夫だったようです。

拍手[0回]

h8300-elfのgccを作ろうとしたら

gcc-4.7.2でh8300-elfをビルドすると


/tmp/ccDjD4Ol.s: Assembler messages:
/tmp/ccDjD4Ol.s:88845: Error: value of 70656 too large for field of 2 bytes at 23321
/tmp/ccDjD4Ol.s:88970: Error: value of 70656 too large for field of 2 bytes at 23515

このメッセージが出て、失敗します。
この回避方法はgcc/config/h8300.hに

/* We want dwarf2 info available to gdb.  */
 #define DWARF2_DEBUGGING_INFO        1
+#define DWARF2_ADDR_SIZE 4


この行を追加します。

で、また、ビルドすると

/home/kenrou/temp/gcc/h8300/h8300-elf/h8300h/normal/int32/libstdc++-v3/include/bits/vector.tcc:397:7: エラー: 二進式内で型不一致です
short int

int


short int

D.116450 = D.116449 /[ex] 4;

/home/kenrou/temp/gcc/h8300/h8300-elf/h8300h/normal/int32/libstdc++-v3/include/bits/vector.tcc:397: 前のエラーにより混乱していますので、脱出します

このメッセージが出て、また、失敗します。これで2回目
回避方法は、gcc/config/t-h8300に赤字の部分を追加します。

MULTILIB_OPTIONS = mh/ms/msx mn mint32
MULTILIB_DIRNAMES = h8300h h8300s h8sx normal int32
MULTILIB_EXCEPTIONS = mint32 mn mn/mint32 mh/mn/mint32 ms/mn/mint32 msx/mn/mint32

作業フォルダのgccとh8300-elfをフォルダ毎、削除してから、ビルドを再開します。
$ rm gcc -fr
$ rm h8300-elf -fr
$ make -j4

なにをしたかを簡単に書くと、ノーマルモードの時にintのサイズが32bitのライブラリは作らないです。

gcc-4.8では、修正済みのようです。






拍手[0回]

gccのh8300部分をちょい直し

gcc/config/h8300/h8300.mdに
"0 /* Disable because it breaks compiling fp-bit.c. */
というところが2箇所あります
ここを1にすると何が起こるかというと

../../../../gcc-4.7.2/libgcc/fp-bit.c: In function ‘__subsf3’:
../../../../gcc-4.7.2/libgcc/fp-bit.c:772:1: error: insn does not satisfy its constraints:
(insn 63 20 22 2 (set (mem/c:QI (plus:SI (reg/f:SI 6 r6)
                (const_int -15 [0xfffffffffffffff1])) [0 b.sign+0 S1 A8])
        (xor:QI (mem/c:QI (plus:SI (reg/f:SI 6 r6)
                    (const_int -15 [0xfffffffffffffff1])) [0 b.sign+0 S1 A8])
            (const_int 1 [0x1]))) ../../../../gcc-4.7.2/libgcc/fp-bit.c:767 170 {xorqi3_1}
     (nil))
../../../../gcc-4.7.2/libgcc/fp-bit.c:772:1: internal compiler error: in
copyprop_hardreg_forward_1, at regcprop.c:767
Please submit a full bug report,with preprocessed source if appropriate.See <http://gcc.gnu.org/bugs.html> for instructions.


上のエラーでビルドが失敗します。

(xor:QIの部分に注目して、どこが間違ってるかを探して見ました。

gcc/config/h8300/h8300.md
@@ -2174,7 +2174,7 @@
   [(set_attr "length" "8")])

 (define_insn "xorqi3_1"
-  [(set (match_operand:QI 0 "bit_operand" "=U,r")
+  [(set (match_operand:QI 0 "bit_operand" "=U,rQ")
        (xor:QI (match_operand:QI 1 "bit_operand" "%0,0")
                (match_operand:QI 2 "h8300_src_operand" "Y2,rQi")))]
   "TARGET_H8300SX || register_operand (operands[0], QImode)

他のbit操作系の記述とと比較すると、Qが抜けてるだけでした。

拍手[0回]

rl78-elf-gccコンパイラ作成手順

基本的にunix系の環境で構築するのを推奨,windows系ならcygwin、msysで
unix系でwindowsで動作可能なコンパイラを作ることもできます。
ただし、その環境を作る作業のほうが難易度高です。

GUIではコンソールの環境で作業します

まずは、binutilsの作成からです。

$ mkdir binutils
作業フォルダの作成
$ cd binutils
そこに移動
$ wget http://www.ring.gr.jp/archives/GNU/binutils/binutils-2.23.1.tar.bz2
本家もしくはミラーサイトよりbinutilsのなるべく最新のものをダウンロード
$ tar xjf binutils-2.23.1.tar.bz2
圧縮ファイルの解凍
$ mkdir build
ビルドフォルダの作成
$ cd build
フォルダに移動
$ ../binutils-2.23.1/configure --prefix=/usr/local -enable-64-bit-bfd --enable-checking=release --target=rl78-elf
configureの実行
$ make -j4
makeの実行(4は4コアの場合)
$ su
スーパーユーザーモードに
# make install
インストール先は/usr/local
# exit
スーパーユーザーモード解除
$ cd ..
$ cd ..
これでbinutilsの作成は終わり

次にgccの作成(最初はライブラリがないため、2回作業が必要)
注 gmp,mpfr,mpcがインストールされていること
$ mkdir gcc
作業フォルダの作成
$ cd gcc
そこに移動
$ wget http://www.ring.gr.jp/archives/lang/egcs/releases/gcc-4.7.2/gcc-4.7.2.tar.bz2
本家もしくはミラーサイトよりなるべく最新のものをダウンロード
$ mkdir build
ビルドフォルダの作成
$ cd build
フォルダに移動
$ tar xjf gcc-4.7.2.tar.bz2
圧縮ファイルの解凍
$ mkdir build
ビルドフォルダの作成
$ cd build
フォルダに移動
$ .../gcc-4.7.2/configure --prefix=/usr/local --enable-checking=release --enable-languages=c --target=rl78-elf
configureの実行
$ make all-gcc all-target-libgcc -j4
Cコンパイラのみを作成
$ su
スーパーユーザーモードに
# make install-gcc install-target-libgcc -j4
インストール先は/usr/local
# exit
スーパーユーザーモード解除
$ cd ..
$ cd ..
初回のgccの作成はここまで
次にnewlibの作成
$ mkdir newlib
作業フォルダの作成
$ cd newlib
そこに移動
ダウンロードと圧縮ファイルの解凍は略
$ mkdir build
$ cd build
$ ../newlib-1.20.0/configure --prefix=/usr/local –target=rl78-elf
configureの実行
$ make -j4
Cコンパイラのみを作成
$ su
スーパーユーザーモードに
# make install -j4
インストール先は/usr/local
# exit
スーパーユーザーモード解除
$ cd ..
$ cd ..
Cコンパイラのみはここまで
最終段階のgccの作成
$ cd gcc
$ rm build -fr
一度、初回作成のフォルダを削除
$ mkdir build
$ cd build
$ .../gcc-4.7.2/configure --prefix=/usr/local --enable-checking=release --enable-languages=c,c++ --target=rl78-elf --with-newlib
configureの実行(c++、newlibを追加)
$ make -j4
$ su
# make install -j4
# exit
$ cd ..
$ cd ..
これでコンパイラの作成は終了
$ rl78-elf-gcc -v
組み込み spec を使用しています。
COLLECT_GCC=rl78-elf-gcc
COLLECT_LTO_WRAPPER=/usr/local/rl78/libexec/gcc/rl78-elf/4.7.2/lto-wrapper
ターゲット: rl78-elf
configure 設定: ../gcc-4.7.2/configure --prefix=/usr/local --enable-checking=release --enable-languages=c,c++ --target=rl78-elf --with-newlib
スレッドモデル: single
gcc バージョン 4.7.2 (GCC)

と表示されれば終わり


拍手[1回]

カレンダー

10 2024/11 12
S M T W T F S
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

フリーエリア

最新CM

最新記事

(07/27)
(03/27)
(03/26)
(03/23)
(03/22)
(03/19)
(03/18)
(03/18)
(03/15)
(03/14)
(03/13)
(03/12)
(03/11)
(03/11)
(03/08)
(03/08)
(03/06)
(03/05)
(03/02)
(03/01)
(02/28)
(02/27)
(02/24)
(02/23)
(02/22)

プロフィール

HN:
kenrou
性別:
非公開

バーコード

ブログ内検索

最古記事

(12/15)
(12/16)
(12/17)
(12/18)
(12/19)
(12/20)
(12/21)
(12/22)
(12/23)
(12/24)
(12/25)
(12/26)
(12/27)
(12/28)
(12/29)
(12/30)
(12/31)
(01/01)
(01/02)
(01/21)
(01/22)
(01/23)
(01/24)
(01/24)
(01/28)

P R

忍者アナライズ

コガネモチ

忍者カウンター

カレンダー

10 2024/11 12
S M T W T F S
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30