11.micropythonのネイティブマシンコード使用時に除算ライブラリが使えないのを対策
8.picocalcでjpegデータを表示したい の続きであり解決編でもある
micropythonでrp2040(rpi pico)でネイティブマシンコードを使うと未定義エラー(__aeabi_idiv)
rp2040のCPU cortex-m0 には除算器がないので、除算を使うとコンパイラは関数コール(__aeabi_idiv)を挿入する。
(除数が定数で2の倍数とかならシフト演算に書き換わる)
この関数は標準ライブラリに入ってるので、普通は気にしなくてよい。
問題は micropython の「ネイティブマシンコードの .mpy ファイルへの埋込み」機能を使うとき。
このときはライブラリを指定できないので、自力で何とかする必要がある。
そこで使用したのが下記
https://github.com/bobbl/libaeabi-cortexm0
他にも使えるのが下記
https://chromium.googlesource.com/chromiumos/platform/ec/+/master/core/cortex-m0/
ただし、これを使うとリンク時にこんなエラーが発生した。
File "/home/user/????/mpy_rp2/../../micropython/tools/mpy_ld.py", line 720, in do_relocation_text
assert 0, (r_info_type, s.name, s.entry, env.arch.name)
^
AssertionError: (102, '__aeabi_uidivmod', Container({'st_name': 132, 'st_value': 1, 'st_size': 0, 'st_info': Container({'bind': 'STB_GLOBAL', 'type': 'STT_FUNC'}), 'st_other': Container({'local': 0, 'visibility': 'STV_DEFAULT'}), 'st_shndx': 8}), 'EM_ARM')
説明が無くてかなり悩んだが「globalシンボルに対しジャンプ」しているときに発生するようだ。
関数コール直後にリターンするときのコーディングが原因。
命令圧縮や高速化のために call function, return の場合は jump function にするのが定番だけどこれが問題。
__aeabi_uidivmod に直接ジャンプしている idiv.S を書き換えて解決
b __aebi_uidivmod
↓
push {lr}
bl__aeabi_uidivmod
pop{pc}