OR命令とORI命令の実装

こんにちは、めのんです!

前回のビット単位のAND演算に続いて、今回はビット単位のOR演算を実装します。

OR命令の実装

まずはOR命令からです。
ビット単位のORについてはとくに説明は必要ないと思います。

それではいつものように「AVR®命令一式手引書」から命令の説明を引用します。

ほとんどOR命令といっしょですね。

コードを見ていきますね。

static void or(atmega328_t *cpu, uint16_t op)
{
  int d = (op >> 4) & 0x1f;
  int r = (op & 0xf) | (op >> 5) & 0x10;
  int value = cpu->r[d] | cpu->r[r];
  cpu->r[d] = value;

  int sr = cpu->sr & ~(flag_S | flag_V | flag_N | flag_Z);
  if (value & 0x80)
    sr |= flag_N | flag_S;
  if (value == 0)
    sr |= flag_Z;
  cpu->sr = sr;

  ++cpu->clock;
}

こちらもand関数とほとんど同じです。
andと同じように、「or」も<iso646.h>で定義されるマクロと同名です。
<iso646.h>をインクルードしていると使えません。

ORI命令の実装

次はORI命令を実装します。

こちらも「AVR®命令一式手引書」から命令の説明を引用します。

ほとんどANDI命令といっしょですね。

では、コードを見ていきます。

static void ori(atmega328_t *cpu, uint16_t op)
{
  int d = 16 + ((op >> 4) & 0xf);
  int K = (op & 0xf) | (op >> 4) & 0xf0;
  int value = cpu->r[d] | K;
  cpu->r[d] = value;

  int sr = cpu->sr & ~(flag_S | flag_V | flag_N | flag_Z);
  if (value & 0x80)
    sr |= flag_N | flag_S;
  if (value == 0)
    sr |= flag_Z;
  cpu->sr = sr;

  ++cpu->clock;
}

とくに説明は必要ないでしょう。

op_tableへの登録

次に、いつものようにop_tableに登録します。

opcode.phpに次のコードを追加して実行してあげればOKです。

for ($i = 0; $i < 1024; ++$i)
{
  $opcode_table[0b0010_1000_0000_0000 | $i] = 'or';
}

for ($i = 0; $i < 4096; ++$i)
{
  $opcode_table[0b0110_0000_0000_0000 | $i] = 'ori';
}

前回同様、今回も65,536命令のうち 1,024 + 4,096 = 5,120 個が埋まりました。

それでは次回またお会いしましょう!