ビット操作
*val に bitfield があり、指定 bit を toggle し、その結果の bit で表示する文字列を変更するという処理。
void hoge(uint8_t *const val, enum config_bit bit, uint16_t text_offset, const char *const str[]) { const uint8_t v = 1 << bit; const char *s = str[0]; *val ^= v; if((*val & v) != 0){ s = str[1]; } string_write(s, text_offset, TEXT_COLOR_YAMADA); }
m68k-xxx-gcc は bset, bclr, bchg など破壊的 bittest を使うと期待したんだが、ソース通りに eor と and を使っていた。むーん。
moveq #1,d1 move.l 28(sp),d0 lsl.l d0,d1 ;v = 1 << bit; move.l (a3),a1 ;*s = str[0] move.b (a2),d0 eor.b d1,d0 move.b d0,(a2) ;*val ^= v and.b d1,d0 beq .L3 ;(*val & v) != 0; 以下略 move.l 4(a3),a1 .L3: pea 17408.w move.w a0,-(sp) clr.w -(sp) move.l a1,-(sp) jsr string_write lea (12,sp),sp
わたしの期待は下記だった。 bchg の z フラグは変更前の値に反映するので注意。bclr は使うかもしれんが、 bchg はコンパイラには実装されづらいわな。
move.l (a3),a1 ;*s = str[0] move.l 28(sp),d0 bchg.b d0,(A2) ;v = 1 << bit; (*val & v) != 0; *val ^= v; beq .L3 moveq #1,d1 move.l 28(sp),d0 move.l 4(a3),a1