xeij/EFPBox.java (3/3)
1 2 3
  //    0x0c  word  read  write  (reserved)               reserved CIRのアクセスはプロトコル違反にならない
  //    0x0e  word        write  condition CIR
  //    0x10  long  read  write  operand CIR
  //    0x14  word  read         register select CIR
  //    0x16  word  read  write  (reserved)               reserved CIRのアクセスはプロトコル違反にならない
  //    0x18  long        write  instruction address CIR
  //    0x1c  long  read  write  operand address CIR      MC68882のみ。MC68881ではwriteは無視、readは-1
  public int cirResponse;  //0x00 response CIRのレスポンス。上位ワードが0でないとき下位ワードを1回だけ出力して次回から上位ワードを出力する
  public int cirFormatWord;  //0x02 save CIRのフォーマットワード
  public int cirOperationWord;  //0x08 operation word CIR
  public int cirCommand;  //0x0a command CIR
  public int cirRegisterList;  //0x14 register select CIRの上位バイト
  public int cirOperandAddress;  //0x1c operand address CIR

  //オペランド
  public final int[] cirOperandBuffer = new int[212];  //ロング単位のオペランドバッファ
  public int cirOperandLength;  //転送中のオペランドのロング数
  public int cirOperandIndex;  //転送中のオペランドの次に転送するロング位置

  //命令の処理段階
  //  MC68882はデスティネーションオペランドの転送が終わる前にレスポンスプリミティブが0x0802になって次のコマンドを受け付けることができる
  //  ここではデスティネーションオペランドの転送が終わるまで次のコマンドを受け付けないことにする
  //  オペランドバッファは転送する直前に構築すること
  //    オペランドバッファを使わない段階ではFSAVEでオペランドバッファを保存しない
  public static final int CIR_INPUT_MASK            =                   16;  //オペランドバッファへ入力中
  public static final int CIR_OUTPUT_MASK           =                   32;  //オペランドバッファから出力中
  public static final int CIR_IDLE                  =                    0;  //アイドル
  public static final int CIR_PROGRAM_COUNTER       =                    1;  //プログラムカウンタをinstruction address CIRへ入力中
  public static final int CIR_DYNAMIC_K_FACTOR      = CIR_INPUT_MASK  |  2;  //動的k-factorをoperand CIRへ入力中
  public static final int CIR_DYNAMIC_REGISTER_LIST = CIR_INPUT_MASK  |  3;  //動的レジスタリストをoperand CIRへ入力中
  public static final int CIR_REGISTER_SELECT       =                    4;  //レジスタセレクトをregister select CIRから出力中
  public static final int CIR_SOURCE_OPERAND        = CIR_INPUT_MASK  |  5;  //ソースオペランドをoperand CIRへ入力中
  public static final int CIR_DESTINATION_OPERAND   = CIR_OUTPUT_MASK |  6;  //デスティネーションオペランドをoperand CIRから出力中
  public static final int CIR_FSAVE_STATE_FRAME     = CIR_OUTPUT_MASK |  7;  //FSAVEのステートフレームをoperand CIRから出力中
  public static final int CIR_FRESTORE_STATE_FRAME  = CIR_INPUT_MASK  |  8;  //FRESTOREのステートフレームをoperand CIRへ入力中
  public static final int CIR_EXCEPTION_PROCESSING  =                    9;  //例外処理中
  public static final String[] cirNameOfStage = {
    "idle",  //0
    "input program counter into the instruction address CIR",  //1
    "input dynamic k-factor into the operand CIR",  //2
    "input dynamic register list into the operand CIR",  //3
    "output register select from the register select CIR",  //4
    "input source operand into the operand CIR",  //5
    "output destination operand from the operand CIR",  //6
    "output FSAVE state frame from the operand CIR",  //7
    "input FRESTORE state from into the operand CIR",  //8
    "exception processing",  //9
  };
  public int cirStage;

  //cirInit ()
  //  初期化
  public final void cirInit () {
    //cirOperandBuffer = new int[212];
    Arrays.fill (cirOperandBuffer, 0);
    cirReset ();
  }  //cirInit()

  //cirReset ()
  //  リセット
  public final void cirReset () {
    cirIdle (0x0802);
  }  //cirReset()

  //cirIdle ()
  //  アイドルに戻す
  public final void cirIdle (int response) {
    if (CIR_DEBUG_TRACE) {
      System.out.printf ("%08x cirIdle(0x%08x)\n", XEiJ.regPC0, response);
    }
    cirResponse = response;
    cirOperationWord = 0;
    cirCommand = 0;
    cirRegisterList = 0;
    cirOperandAddress = 0;
    Arrays.fill (cirOperandBuffer, 0);
    cirOperandLength = 0;
    cirOperandIndex = 0;
    cirStage = CIR_IDLE;
  }  //cirIdle(int)

  //cirException (response)
  //  例外発生
  //  プロトコル違反以外はsave CIRをリードしてアイドルステートフレームを保存するとヌルプリミティブに戻る
  //  プロトコル違反はcontrol CIRに書き込んで復帰させる
  //  response CIRに$0000を書き込む方法でも復帰できる
  //    --------------------------------
  //    オペランドエラーは次のコマンドをフェッチしたとき発生する
  //    > cir 00 .
  //    0802 
  //    > cir 0a 9800
  //    > cir 00 ....
  //    8900 9608 8900 8900 
  //    > cir 10 00002000 00000000
  //    > cir 00 ..
  //    0802 0802 
  //    > cir 0a 4000
  //    > cir 00 ..
  //    D504 8900 
  //    > cir 18 00000000
  //    > cir 00 ..
  //    8900 8900 
  //    > cir 10 00000000
  //    > cir 00 ..
  //    0802 0802 
  //    > cir 0a 4020
  //    > cir 00 ..
  //    D504 8900 
  //    > cir 18 00000000
  //    > cir 00 ..
  //    8900 8900 
  //    > cir 10 00000000
  //    > cir 00 .
  //    0802 
  //    > cir 00 .
  //    0802 
  //    > cir 00 .
  //    0802 
  //    > cir 0a 0000
  //    > cir 00 .
  //    1C34 
  //    > cir 06 0000
  //    > cir 00 ..
  //    0802 0802 
  //    --------------------------------
  //    ゼロ除算は次のコマンドをフェッチしたとき発生する
  //    fmovem.l #$00000400,#$00000000,fpcr/fpsr
  //    fmove.l #1,fp0
  //    fdiv.l #0,fp0
  //    fmove.x fp0,fp0
  //    > cir 00 .
  //    0802 
  //    > cir 0a 9800
  //    > cir 00 ....
  //    8900 9608 8900 8900 
  //    > cir 10 00000400 00000000
  //    > cir 00 ..
  //    0802 0802 
  //    > cir 0a 4000
  //    > cir 00 ..
  //    D504 8900 
  //    > cir 18 00000000
  //    > cir 00 ..
  //    8900 8900 
  //    > cir 10 00000001
  //    > cir 00 ..
  //    0802 0802 
  //    > cir 0a 4020
  //    > cir 00 ..
  //    D504 8900 
  //    > cir 18 00000000
  //    > cir 00 ..
  //    8900 8900 
  //    > cir 10 00000000
  //    > cir 00 .
  //    0802 
  //    > cir 00 .
  //    0802 
  //    > cir 00 .
  //    0802 
  //    > cir 0a 0000
  //    > cir 00 .
  //    1C32 
  //    > cir 06 0000
  //    > cir 00 ..
  //    0802 0802 
  //    --------------------------------
  //    プロトコル違反はFSAVEで復帰できない
  //    > cir 00 .
  //    0802 
  //    > cir 10 .
  //    9800FFFF 
  //    > cir 00 .
  //    1D0D 
  //    > cir 04 .
  //    0038 
  //    > cir 00 .
  //    1D0D 
  //    > cir 10 .
  //    9800FFFF 
  //    > cir 04 .
  //    0038 
  //    > cir 06 0000
  //    > cir 00 .
  //    0802 
  //    --------------------------------
  //    オペランドエラーはFSAVEで復帰できる
  //    fmovem.l #$00002000,#$00000000,fpcr/fpsr
  //    fmove.l #0,fp0
  //    fdiv.l fp0,fp0
  //    fmove.x fp0,fp0
  //    > cir 00 .
  //    0802 
  //    > cir 0a 9800
  //    > cir 00 ....
  //    8900 9608 8900 8900 
  //    > cir 10 00002000 00000000
  //    > cir 00 ..
  //    0802 0802 
  //    > cir 0a 4000
  //    > cir 00 ..
  //    D504 8900 
  //    > cir 18 00000000
  //    > cir 00 ..
  //    8900 8900 
  //    > cir 10 00000000
  //    > cir 00 ..
  //    0802 0802 
  //    > cir 0a 0020
  //    > cir 00 ..
  //    4900 8900 
  //    > cir 18 00000000
  //    > cir 00 ..
  //    0802 0802 
  //    > cir 0a 0000
  //    > cir 00 ..
  //    1C34 1C34 
  //    > cir 04 .
  //    1F38 
  //    > cir 00 ..
  //    1C34 1C34 
  //    > cir 10 ..............
  //    340EFFFF 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0F000000 00200000 4F800000 00000020 
  //    > cir 00 ..
  //    0802 0802 
  //    > cir 04 .
  //    1F38 
  //    > cir 10 ..............
  //    7C0EFFFF 00000020 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0F000000 00200000 00000000 00000020 
  //    > cir 00 ..
  //    0802 0802 
  //    --------------------------------
  //    FRESTOREに失敗したら$B704というマニュアルに書かれていないレスポンスプリミティブが出てきた
  //    > cir 00 .
  //    0802 
  //    > cir 0a 4000
  //    > cir 00 ....
  //    9504 8900 8900 8900 
  //    > cir 04 .
  //    1FD4 
  //    > cir 10 .....................................................
  //    4C0CFFFF 00000020 40000840 4FFFC000 40000000 3F800000 12C00000 12C00000 12C00000 12C00000 12C00000 00000800 00000000 00000000 00000000 00080000 00000000 00000000 0FFFC000 00000000 00000000 3243F6A8 885A308D 30000000 00080000 00000000 00000000 00010000 4FFFC000 3FFFFFFF FFFFFFFF C0000000 40034000 3D5C0000 00000000 00000000 BFFF4000 3243F6A8 885A308D 40000000 30000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0F000000 40000000 0F800000 4000FFFF 
  //    > cir 00 ..
  //    0802 0802 
  //    > cir 0a 4080
  //    > cir 00 ....
  //    9504 8900 8900 8900 
  //    > cir 10 00000081
  //    > cir 00 ..
  //    0802 0802 
  //    > cir 06 1FD4
  //    > cir 00 ..
  //    0900 0900 
  //    > cir 10 4C0CFFFF 00000020 40000840 4FFFC000 40000000 3F800000 12C00000 12C00000 12C00000 12C00000 12C00000 00000800 00000000 00000000 00000000 00080000 00000000 00000000 0FFFC000 00000000 00000000 3243F6A8 885A308D 30000000 00080000 00000000 00000000 00010000 4FFFC000 3FFFFFFF FFFFFFFF C0000000 40034000 3D5C0000 00000000 00000000 BFFF4000 3243F6A8 885A308D 40000000 30000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0F000000 40000000 0F800000 4000FFFF
  //    > cir 00 ..
  //    0900 0900 
  //    > cir 10 00000000
  //    > cir 00 ..
  //    0900 0900 
  //    > cir 10 00000000
  //    > cir 00 ..
  //    0900 0900 
  //    > cir 10 0 0 0 0 0 0 0 0 0 0
  //    > cir 00 ..
  //    0900 0900 
  //    > cir 10 0 0 0 0 0 0 0 0 0 0
  //    > cir 00 ..
  //    0900 0900 
  //    > cir 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  //    ここでバスエラーが出た
  //    > cir 00 ..
  //    B704 8900 
  //    --------------------------------
  public void cirException (int response) {
    if (CIR_DEBUG_TRACE) {
      System.out.printf ("%08x cirException(0x%08x)\n", XEiJ.regPC0, response);
    }
    cirResponse = response;
    cirOperationWord = 0;
    cirCommand = 0;
    cirRegisterList = 0;
    cirOperandAddress = 0;
    Arrays.fill (cirOperandBuffer, 0);
    cirOperandLength = 0;
    cirOperandIndex = 0;
    cirStage = CIR_EXCEPTION_PROCESSING;
  }  //cirException(int)

  //d = cirPeekByteZero (a)
  //  ピークバイトゼロ拡張
  public int cirPeekByteZero (int a) {
    return (a & 1) == 0 ? cirPeekWordZero (a) >>> 8 : cirPeekWordZero (a - 1) & 255;
  }  //cirPeekByteZero(int)

  //d = cirPeekWordZero (a)
  //  ピークワードゼロ拡張
  public int cirPeekWordZero (int a) {
    a &= 0x1e;  //bit0は無視される
    int d = 65535;
    switch (a) {
    case 0x00:  //response
      d = (char) cirResponse;  //下位ワードを出力する
      break;
      //case 0x02:  //control
    case 0x04:  //save
      if ((cirStage == CIR_EXCEPTION_PROCESSING && cirResponse == 0x1d0d) ||  //プロトコル違反はFSAVEで復帰できない
          cirStage == CIR_FSAVE_STATE_FRAME ||
          cirStage == CIR_FRESTORE_STATE_FRAME) {  //FSAVE/FRESTOREの動作中はFSAVE/FRESTOREできない
        d = 0x0200;
        //プロトコル違反
      } else {
        if ((cirStage & (CIR_INPUT_MASK | CIR_OUTPUT_MASK)) == 0) {  //オペランドバッファを使わない段階
          d = 0x1f38;  //アイドルステート。0x38/4=56バイト/4=14ロング
        } else {  //オペランドバッファを使う段階
          d = 0x1fd4;  //ビジーステート。0xd4/4=212バイト/4=53ロング
        }
      }
      break;
    case 0x06:  //restore
      d = (char) cirFormatWord;
      break;
    case 0x08:  //operation word
      d = (char) cirOperationWord;
      break;
      //case 0x0a:  //command
      //case 0x0c:  //(reserved)
      //reserved CIRのアクセスはプロトコル違反にならない
      //case 0x0e:  //condition
    case 0x10 + 0:  //operand CIRの上位ワード
      //fmove.w fp0,<ea>で使う
      d = cirPeekLong (a) >>> 16;
      break;
    case 0x10 + 2:  //operand CIRの下位ワード
      d = (char) cirPeekLong (a + 2);
      break;
    case 0x14:  //register select
      if (cirStage == CIR_REGISTER_SELECT) {
        //  複数レジスタ転送プリミティブの直後に1回だけ有効
        //  上位バイトにレジスタリストが示される
        //  MPUは1の数を数えて転送するデータの長さを確定する
        //  ビットの並び順(どのデータがどのレジスタに格納されるか)はMPUが把握する必要はない
        d = cirRegisterList << 8;
      } else {
        //プロトコル違反
      }
      break;
      //case 0x16:  //(reserved)
      //reserved CIRのアクセスはプロトコル違反にならない
      //case 0x18:  //instruction address
      //case 0x1c:  //operand address
    case 0x1c + 0:  //operand address CIRの上位ワード
      d = cirPeekLong (a) >>> 16;
      break;
    case 0x1c + 2:  //operand address CIRの下位ワード
      d = (char) cirPeekLong (a - 2);
      break;
    }
    return d;
  }  //cirPeekWordZero(int)

  //d = cirPeekLong (a)
  //  ピークロング
  public int cirPeekLong (int a) {
    a &= 0x1e;  //bit0は無視される
    int d = -1;
    switch (a) {
      //case 0x00:  //response
      //case 0x02:  //control
      //case 0x04:  //save
      //case 0x06:  //restore
      //case 0x08:  //operation word
      //case 0x0a:  //command
      //case 0x0c:  //(reserved)
      //reserved CIRのアクセスはプロトコル違反にならない
      //case 0x0e:  //condition
    case 0x10:  //operand
      if (cirStage == CIR_DESTINATION_OPERAND && cirOperandIndex < cirOperandLength) {  //デスティネーションオペランドの出力中
        d = cirOperandBuffer[cirOperandIndex];
      } else if (cirStage == CIR_FSAVE_STATE_FRAME && cirOperandIndex < cirOperandLength) {  //FSAVEのステートフレームの出力中
        d = cirOperandBuffer[cirOperandLength - cirOperandIndex - 1];  //FSAVEのステートフレームはロング単位で逆順に出力する
      } else {  //オペランドが準備されていないのに読み出そうとした
        //!!! プロトコル違反のとき最後に出力した値が返る
        //プロトコル違反
      }
      break;
      //case 0x14:  //register select
      //case 0x16:  //(reserved)
      //reserved CIRのアクセスはプロトコル違反にならない
      //case 0x18:  //instruction address
    case 0x1c:  //operand address
      d = cirOperandAddress;
      break;
    }
    return d;
  }  //cirPeekLong(int)

  //d = cirReadByteZero (a)
  //  リードバイトゼロ拡張
  public int cirReadByteZero (int a) {
    //リードすると状態が変化してしまうので半分だけリードできてもあまり意味がない
    return (a & 1) == 0 ? cirReadWordZero (a) >>> 8 : cirReadWordZero (a - 1) & 255;
  }  //cirReadByteZero(int)

  //d = cirReadWordZero (a)
  //  リードワードゼロ拡張
  public int cirReadWordZero (int a) {
    a &= 0x1e;  //bit0は無視される
    int d = 65535;
    switch (a) {
    case 0x00:  //response
      d = (char) cirResponse;  //下位ワードを出力する
      if (d != cirResponse) {  //上位ワードが0でないとき
        cirResponse >>>= 16;  //次回から上位ワードを出力する
        if (d == 0x0802) {  //null
          cirIdle (0x0802);
        }
      }
      break;
      //case 0x02:  //control
    case 0x04:  //save
      if ((cirStage == CIR_EXCEPTION_PROCESSING && cirResponse == 0x1d0d) ||  //プロトコル違反はFSAVEで復帰できない
          cirStage == CIR_FSAVE_STATE_FRAME ||
          cirStage == CIR_FRESTORE_STATE_FRAME) {  //FSAVE/FRESTOREの動作中はFSAVE/FRESTOREできない
        d = 0x0200;
        cirException (0x1d0d);  //プロトコル違反
      } else {
        int i;
        if ((cirStage & (CIR_INPUT_MASK | CIR_OUTPUT_MASK)) == 0) {  //オペランドバッファを使わない段階
          d = 0x1f38;  //アイドルステート。0x38/4=56バイト/4=14ロング
          i = 0;
        } else {  //オペランドバッファを使う段階
          d = 0x1fd4;  //ビジーステート。0xd4/4=212バイト/4=53ロング
          i = 3 * 8;  //オペランドが12バイト*8/4=24ロングあるのでその後
        }
        //FSAVEとFRESTOREのステートフレームの構造が同じになるように注意すること
        cirOperandBuffer[i++] = epbFpcr;
        cirOperandBuffer[i++] = epbFpsr;
        cirOperandBuffer[i++] = epbFpiar;
        cirOperandBuffer[i++] = epbQuotient;
        cirOperandBuffer[i++] = epbRoundingPrec;
        cirOperandBuffer[i++] = epbRoundingMode;
        cirOperandBuffer[i++] = cirResponse;
        cirOperandBuffer[i++] = cirFormatWord;
        cirOperandBuffer[i++] = cirOperationWord;
        cirOperandBuffer[i++] = cirCommand;
        cirOperandBuffer[i++] = cirRegisterList;
        cirOperandBuffer[i++] = cirOperandAddress;
        cirOperandBuffer[i++] = cirOperandLength;
        cirOperandBuffer[i++] = cirOperandIndex;
        cirOperandBuffer[i++] = cirStage;
        cirFormatWord = d;
        cirOperandLength = (d & 255) >>> 2;
        cirOperandIndex = 0;
        cirStage = CIR_FSAVE_STATE_FRAME;
        cirResponse = 0x0900;
      }
      break;
    case 0x06:  //restore
      d = (char) cirFormatWord;
      break;
    case 0x08:  //operation word
      d = (char) cirOperationWord;
      break;
      //case 0x0a:  //command
      //case 0x0c:  //(reserved)
      //reserved CIRのアクセスはプロトコル違反にならない
      //case 0x0e:  //condition
    case 0x10 + 0:  //operand CIRの上位ワード
      //fmove.w fp0,<ea>で使う
      d = cirReadLong (a) >>> 16;
      break;
    case 0x10 + 2:  //operand CIRの下位ワード
      d = (char) cirReadLong (a + 2);
      break;
    case 0x14:  //register select
      if (cirStage == CIR_REGISTER_SELECT) {
        //  複数レジスタ転送プリミティブの直後に1回だけ有効
        //  上位バイトにレジスタリストが示される
        //  MPUは1の数を数えて転送するデータの長さを確定する
        //  ビットの並び順(どのデータがどのレジスタに格納されるか)はMPUが把握する必要はない
        d = cirRegisterList << 8;
        cirGen ();
      } else {
        cirException (0x1d0d);  //プロトコル違反
      }
      break;
      //case 0x16:  //(reserved)
      //reserved CIRのアクセスはプロトコル違反にならない
      //case 0x18:  //instruction address
      //case 0x1c:  //operand address
    case 0x1c + 0:  //operand address CIRの上位ワード
      d = cirReadLong (a) >>> 16;
      break;
    case 0x1c + 2:  //operand address CIRの下位ワード
      d = (char) cirReadLong (a - 2);
      break;
    }
    if (CIR_DEBUG_TRACE) {
      System.out.printf ("%08x cirReadWordZero(0x%08x,0x%04x)\n", XEiJ.regPC0, a, d);
    }
    return d;
  }  //cirReadWordZero(int)

  //d = cirReadLong (a)
  //  リードロング
  public int cirReadLong (int a) {
    a &= 0x1e;  //bit0は無視される
    int d = -1;
    switch (a) {
      //case 0x00:  //response
      //case 0x02:  //control
      //case 0x04:  //save
      //case 0x06:  //restore
      //case 0x08:  //operation word
      //case 0x0a:  //command
      //case 0x0c:  //(reserved)
      //reserved CIRのアクセスはプロトコル違反にならない
      //case 0x0e:  //condition
    case 0x10:  //operand
      if (cirStage == CIR_DESTINATION_OPERAND && cirOperandIndex < cirOperandLength) {  //デスティネーションオペランドの出力中
        d = cirOperandBuffer[cirOperandIndex];
        cirOperandIndex++;
        if (cirOperandIndex == cirOperandLength) {  //転送終了
          cirGen ();
        }
      } else if (cirStage == CIR_FSAVE_STATE_FRAME && cirOperandIndex < cirOperandLength) {  //FSAVEのステートフレームの出力中
        d = cirOperandBuffer[cirOperandLength - cirOperandIndex - 1];  //FSAVEのステートフレームはロング単位で逆順に出力する
        cirOperandIndex++;
        if (cirOperandIndex == cirOperandLength) {  //転送終了
          cirIdle (0x0802);
        }
      } else {  //オペランドが準備されていないのに読み出そうとした
        //!!! プロトコル違反のとき最後に出力した値が返る
        cirException (0x1d0d);  //プロトコル違反
      }
      break;
      //case 0x14:  //register select
      //case 0x16:  //(reserved)
      //reserved CIRのアクセスはプロトコル違反にならない
      //case 0x18:  //instruction address
      //case 0x1c:  //operand address
    case 0x1c:  //operand address
      d = cirOperandAddress;
      break;
    }
    if (CIR_DEBUG_TRACE) {
      System.out.printf ("%08x cirReadLong(0x%08x,0x%08x)\n", XEiJ.regPC0, a, d);
    }
    return d;
  }  //cirReadLong(int)

  //cirWriteByte (a, d)
  //  ライトバイト
  public void cirWriteByte (int a, int d) {
  }  //cirWriteByte(int,int)

  //cirWriteWord (a, d)
  //  ライドワード
  public void cirWriteWord (int a, int d) {
    if (CIR_DEBUG_TRACE) {
      System.out.printf ("%08x cirWriteWordZero(0x%08x,0x%04x)\n", XEiJ.regPC0, a, d);
    }
    d &= 65535;
    switch (a & 0x1e) {  //bit0は無視される
      //case 0x00:  //response
    case 0x02:  //control
      //MC68881はデータに関係なくアボート
      //MC68882はbit0(AB abort)に1を書き込むとアボート、bit1(XA exception acknowledge)に1を書き込むと例外クリア
      //ここでは例外が発生していればデータに関係なく例外クリア、さもなくばbit0に1を書き込んだときアボートとする
      if (cirStage == CIR_EXCEPTION_PROCESSING) {  //例外が発生している
        cirIdle (0x0802);  //例外クリア
        return;
      } else if ((d & 1) != 0) {  //bit0に1を書き込んだ
        cirIdle (0x0802);  //アボート
        return;
      }
      break;
      //case 0x04:  //save
    case 0x06:  //restore
      if (d >>> 8 == 0) {  //ヌルステート
        cirFormatWord = d;
        //fp0-fp7はすべてNon-signaling NaNになる
        for (int n = 0; n < 8; n++) {
          epbFPn[n].setnan ();
        }
        //FPCRとFPSRはゼロクリアされる
        epbFpcr = 0;
        epbFpsr = 0;
        cirIdle (0x0802);
      } else if (d == 0x1f38 || d == 0x1fd4) {
        cirFormatWord = d;
        cirOperandLength = (d & 255) >>> 2;
        cirOperandIndex = 0;
        cirStage = CIR_FRESTORE_STATE_FRAME;
        cirResponse = 0x0900;
      } else {
        cirFormatWord = 0x0200;
      }
      return;
    case 0x08:  //operation word
      //MC68881のときwriteは無視、readは-1
      //MC68882のときF-line命令を書き込む。FPCPは使わない
      cirOperationWord = d;
      return;
    case 0x0a:  //command
      if (cirStage == CIR_IDLE) {
        cirCommand = d;
        cirGen ();
        return;
      }
      break;
    case 0x0c:  //(reserved)
      //reserved CIRのアクセスはプロトコル違反にならない
      return;
    case 0x0e:  //condition
      //!!! 命令の実行中に条件判断を要求されたときは命令の処理が終わってから条件判断を行う
      if (cirStage == CIR_IDLE) {
        d &= 0x3f;
        if ((d & 0x20) != 0 && (epbFpsr & XEiJ.FPU_FPSR_NAN) != 0) {  //IEEEノンアウェアテストでNANがセットされているとき
          epbFpsr |= XEiJ.FPU_FPSR_EXC_BSUN;  //BSUNをセット
          epbFpsr |= XEiJ.FPU_FPSR_EXC_TO_AEXC[epbFpsr >> 8 & 255];
          if ((epbFpcr & XEiJ.FPU_FPCR_BSUN) != 0) {  //BSUN例外許可
            cirException (0x5c30);  //BSUN
            return;
          }
        }
        cirResponse = XEiJ.FPU_CCMAP_882[d << 4 | epbFpsr >> 24 & 15] ? 0x0802_0801 : 0x0802_0800;
        return;
      }
      break;
      //case 0x10:  //operand
      //case 0x14:  //register select
    case 0x16:  //(reserved)
      //reserved CIRのアクセスはプロトコル違反にならない
      return;
      //case 0x18:  //instruction address
      //case 0x1c:  //operand address
    }
    cirException (0x1d0d);  //プロトコル違反
  }  //cirWriteWord(int,int)

  //cirWriteLong (a, d)
  //  ライドロング
  public void cirWriteLong (int a, int d) {
    if (CIR_DEBUG_TRACE) {
      System.out.printf ("%08x cirWriteLongZero(0x%08x,0x%08x)\n", XEiJ.regPC0, a, d);
    }
    switch (a & 0x1e) {  //bit0は無視される
      //case 0x00:  //response
      //case 0x02:  //control
      //case 0x04:  //save
      //case 0x06:  //restore
      //case 0x08:  //operation word
      //case 0x0a:  //command
    case 0x0c:  //(reserved)
      //reserved CIRのアクセスはプロトコル違反にならない
      return;
      //case 0x0e:  //condition
    case 0x10:  //operand
      if ((cirStage & CIR_INPUT_MASK) != 0 && cirOperandIndex < cirOperandLength) {
        cirOperandBuffer[cirOperandIndex++] = d;
        if (cirOperandIndex == cirOperandLength) {  //転送終了
          if (cirStage == CIR_DYNAMIC_K_FACTOR ||
              cirStage == CIR_DYNAMIC_REGISTER_LIST ||
              cirStage == CIR_SOURCE_OPERAND) {
            cirGen ();
          } else if (cirStage == CIR_FRESTORE_STATE_FRAME) {
            int i = cirFormatWord == 0x1f38 ? 0 : 3 * 8;
            //FSAVEとFRESTOREのステートフレームの構造が同じになるように注意すること
            epbFpcr = cirOperandBuffer[i++] & EPB_FPCR_ALL;
            epbFpsr = cirOperandBuffer[i++] & EPB_FPSR_ALL;
            epbFpiar = cirOperandBuffer[i++];
            epbQuotient = cirOperandBuffer[i++];
            epbRoundingPrec = cirOperandBuffer[i++];
            epbRoundingMode = cirOperandBuffer[i++];
            cirResponse = cirOperandBuffer[i++];
            cirFormatWord = cirOperandBuffer[i++];
            cirOperationWord = cirOperandBuffer[i++];
            cirCommand = cirOperandBuffer[i++];
            cirRegisterList = cirOperandBuffer[i++];
            cirOperandAddress = cirOperandBuffer[i++];
            cirOperandLength = cirOperandBuffer[i++];
            cirOperandIndex = cirOperandBuffer[i++];
            cirStage = cirOperandBuffer[i++];
          }
        }
        return;
      }
      break;
      //case 0x14:  //register select
    case 0x16:  //(reserved)
      //reserved CIRのアクセスはプロトコル違反にならない
      return;
    case 0x18:  //instruction address
      if (cirStage == CIR_PROGRAM_COUNTER) {
        //FMOVEM/FMOVE FPcr/FSAVE/FRESTORE以外の命令でFPCRのException Enable Byte(bit15-8)が0でないときデータ転送プリミティブのPC(bit14)がセットされる
        //データ転送プリミティブのPC(bit14)がセットされているときデータ転送の前にinstruction address CIRにPCを書き込まないとプロトコル違反になる
        epbFpiar = d;
        cirGen ();
        return;
      }
      break;
    case 0x1c:  //operand address
      cirOperandAddress = d;
      break;
    }
    cirException (0x1d0d);  //プロトコル違反
  }  //cirWriteLong(int,int)


  //cirGen ()
  //  一般命令の処理
  //  コマンドを開始するときと転送が終了したときに呼び出される
  //  cirStageがCIR_IDLEのときは最初から、それ以外は途中から処理する
  @SuppressWarnings ("fallthrough") public void cirGen () {
    if (CIR_DEBUG_TRACE) {
      System.out.printf ("%08x cirGen(command=0x%04x,stage=%d(%s))\n", XEiJ.regPC0, cirCommand, cirStage, cirNameOfStage[cirStage & 15]);
    }

    //  111111
    //  5432109876543210
    //  hhhmmmnnnccccccc
    int mmm = cirCommand >> 10 & 7;  //ソースオペランド
    int nnn = cirCommand >> 7 & 7;  //デスティネーションオペランド
    int ccccccc = cirCommand & 0x7f;


    switch (cirCommand >> 13) {


    case 0b010:  //$4xxx-$5xxx: Fop.* <ea>,FPn
      if (cirStage == CIR_IDLE) {  //開始
        epbFpsr &= 0x00ff00ff;
        epbSetRoundingPrec (epbFpcr >> 6 & 3);  //丸め桁数
        epbSetRoundingMode (epbFpcr >> 4 & 3);  //丸めモード
      }

      switch (mmm) {

      case 0b000:  //$40xx-$43xx: Fop.L <ea>,FPn
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a 4000
        //    > cir 00 ...
        //    9504 8900 8900 
        //    > cir 10 00000001
        //    > cir 00 ..
        //    0802 0802 
        //    --------------------------------
        if (cirStage == CIR_IDLE) {  //開始
          if ((epbFpcr & 0x0000ff00) != 0) {  //例外処理あり
            cirResponse = 0x8900_d504;  //PCを入力する→ロングのデータを入力する→come-again
            cirStage = CIR_PROGRAM_COUNTER;  //PC転送開始
          } else {
            cirResponse = 0x8900_9504;  //ロングのデータを入力する→come-again
            cirOperandLength = 1;
            cirOperandIndex = 0;
            cirStage = CIR_SOURCE_OPERAND;  //ソースオペランド転送開始
          }
          return;
        }
        if (cirStage == CIR_PROGRAM_COUNTER) {  //PC転送終了
          cirOperandLength = 1;
          cirOperandIndex = 0;
          cirStage = CIR_SOURCE_OPERAND;  //ソースオペランド転送開始
          return;
        }
        if (cirStage == CIR_SOURCE_OPERAND) {  //ソースオペランド転送終了
          epbFPn[mmm = EPB_SRC_TMP].seti (cirOperandBuffer[0]);
          if (cirPreInstruction ()) {
            return;
          }
        }
        break;

      case 0b001:  //$44xx-$47xx: Fop.S <ea>,FPn
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a 4400
        //    > cir 00 ...
        //    1504 8900 8900 
        //    > cir 10 00000000
        //    > cir 00 ..
        //    0802 0802 
        //    --------------------------------
        if (cirStage == CIR_IDLE) {  //開始
          if ((epbFpcr & 0x0000ff00) != 0) {  //例外処理あり
            if ((epbMode & EPB_MODE_MC68882) != 0) {  //MC68882
              cirResponse = 0x8900_5504;  //PCを入力する→シングルのデータを入力する→come-again
            } else {  //MC68881
              cirResponse = 0x8900_d504;  //PCを入力する→シングルのデータを入力する→come-again
            }
            cirStage = CIR_PROGRAM_COUNTER;  //PC転送開始
          } else {
            if ((epbMode & EPB_MODE_MC68882) != 0) {  //MC68882
              cirResponse = 0x8900_1504;  //シングルのデータを入力する→come-again
            } else {  //MC68881
              cirResponse = 0x8900_9504;  //シングルのデータを入力する→come-again
            }
            cirOperandLength = 1;
            cirOperandIndex = 0;
            cirStage = CIR_SOURCE_OPERAND;  //ソースオペランド転送開始
          }
          return;
        }
        if (cirStage == CIR_PROGRAM_COUNTER) {  //PC転送終了
          cirOperandLength = 1;
          cirOperandIndex = 0;
          cirStage = CIR_SOURCE_OPERAND;  //ソースオペランド転送開始
          return;
        }
        if (cirStage == CIR_SOURCE_OPERAND) {  //ソースオペランド転送終了
          epbFPn[mmm = EPB_SRC_TMP].setf0 (cirOperandBuffer[0]);
          if (cirPreInstruction ()) {
            return;
          }
        }
        break;

      case 0b010:  //$48xx-$4Bxx: Fop.X <ea>,FPn
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a 4800
        //    > cir 00 ...
        //    160C 8900 8900 
        //    > cir 10 00000000
        //    > cir 00 ..
        //    8900 8900 
        //    > cir 10 00000000
        //    > cir 00 ..
        //    8900 8900 
        //    > cir 10 00000000
        //    > cir 00 ..
        //    0802 0802 
        //    --------------------------------
        if (cirStage == CIR_IDLE) {  //開始
          if ((epbFpcr & 0x0000ff00) != 0) {  //例外処理あり
            if ((epbMode & EPB_MODE_MC68882) != 0) {  //MC68882
              cirResponse = 0x8900_560c;  //PCを入力する→エクステンデッドのデータを入力する→come-again
            } else {  //MC68881
              cirResponse = 0x8900_d60c;  //PCを入力する→エクステンデッドのデータを入力する→come-again
            }
            cirStage = CIR_PROGRAM_COUNTER;  //PC転送開始
          } else {
            if ((epbMode & EPB_MODE_MC68882) != 0) {  //MC68882
              cirResponse = 0x8900_160c;  //エクステンデッドのデータを入力する→come-again
            } else {  //MC68881
              cirResponse = 0x8900_960c;  //エクステンデッドのデータを入力する→come-again
            }
            cirOperandLength = 3;
            cirOperandIndex = 0;
            cirStage = CIR_SOURCE_OPERAND;  //ソースオペランド転送開始
          }
          return;
        }
        if (cirStage == CIR_PROGRAM_COUNTER) {  //PC転送終了
          cirOperandLength = 3;
          cirOperandIndex = 0;
          cirStage = CIR_SOURCE_OPERAND;  //ソースオペランド転送開始
          return;
        }
        if (cirStage == CIR_SOURCE_OPERAND) {  //ソースオペランド転送終了
          if (epbIsTriple ()) {  //三倍精度
            epbFPn[mmm = EPB_SRC_TMP].sety012 (cirOperandBuffer[0], (long) cirOperandBuffer[1] << 32 | cirOperandBuffer[2] & 0xffffffffL);
          } else {  //拡張精度
            epbFPn[mmm = EPB_SRC_TMP].setx012 (cirOperandBuffer[0], (long) cirOperandBuffer[1] << 32 | cirOperandBuffer[2] & 0xffffffffL);
          }
          if (cirPreInstruction ()) {
            return;
          }
        }
        break;

      case 0b011:  //$4Cxx-$4Fxx: Fop.P <ea>,FPn
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a 4c00
        //    > cir 00 ....
        //    8900 960C 8900 8900 
        //    > cir 10 00000000
        //    > cir 00 ..
        //    8900 8900 
        //    > cir 10 00000000
        //    > cir 00 ..
        //    8900 8900 
        //    > cir 10 00000000
        //    > cir 00 ..
        //    0802 0802 
        //    --------------------------------
        if (cirStage == CIR_IDLE) {  //開始
          if ((epbFpcr & 0x0000ff00) != 0) {  //例外処理あり
            cirResponse = 0x8900_d60c;  //PCを入力する→パックトのデータを入力する→come-again
            cirStage = CIR_PROGRAM_COUNTER;  //PC転送開始
          } else {
            cirResponse = 0x8900_960c;  //パックトのデータを入力する→come-again
            cirOperandLength = 3;
            cirOperandIndex = 0;
            cirStage = CIR_SOURCE_OPERAND;  //ソースオペランド転送開始
          }
          return;
        }
        if (cirStage == CIR_PROGRAM_COUNTER) {  //PC転送終了
          cirOperandLength = 3;
          cirOperandIndex = 0;
          cirStage = CIR_SOURCE_OPERAND;  //ソースオペランド転送開始
          return;
        }
        if (cirStage == CIR_SOURCE_OPERAND) {  //ソースオペランド転送終了
          epbFPn[mmm = EPB_SRC_TMP].setp012 (cirOperandBuffer[0], (long) cirOperandBuffer[1] << 32 | cirOperandBuffer[2] & 0xffffffffL);
          if (cirPreInstruction ()) {
            return;
          }
        }
        break;

      case 0b100:  //$50xx-$53xx: Fop.W <ea>,FPn
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a 5000
        //    > cir 00 ...
        //    9502 8900 8900 
        //    > cir 10 00010002
        //    > cir 00 ..
        //    0802 0802 
        //    > cir 0a 6000
        //    > cir 00 ...
        //    8900 B104 0802 
        //    > cir 10 .
        //    00000001 
        //    > cir 00 ..
        //    0802 0802 
        //    --------------------------------
        if (cirStage == CIR_IDLE) {  //開始
          if ((epbFpcr & 0x0000ff00) != 0) {  //例外処理あり
            cirResponse = 0x8900_d502;  //PCを入力する→ワードのデータを入力する→come-again
            cirStage = CIR_PROGRAM_COUNTER;  //PC転送開始
          } else {
            cirResponse = 0x8900_9502;  //ワードのデータを入力する→come-again
            cirOperandLength = 1;
            cirOperandIndex = 0;
            cirStage = CIR_SOURCE_OPERAND;  //ソースオペランド転送開始
          }
          return;
        }
        if (cirStage == CIR_PROGRAM_COUNTER) {  //PC転送終了
          cirOperandLength = 1;
          cirOperandIndex = 0;
          cirStage = CIR_SOURCE_OPERAND;  //ソースオペランド転送開始
          return;
        }
        if (cirStage == CIR_SOURCE_OPERAND) {  //ソースオペランド転送終了
          epbFPn[mmm = EPB_SRC_TMP].seti (cirOperandBuffer[0] >> 16);  //左詰めになっている
          if (cirPreInstruction ()) {
            return;
          }
        }
        break;

      case 0b101:  //$54xx-$57xx: Fop.D <ea>,FPn
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a 5400
        //    > cir 00 ...
        //    1608 8900 8900 
        //    > cir 10 00000000
        //    > cir 00 ..
        //    8900 8900 
        //    > cir 10 00000000
        //    > cir 00 ..
        //    0802 0802 
        //    --------------------------------
        if (cirStage == CIR_IDLE) {  //開始
          if ((epbFpcr & 0x0000ff00) != 0) {  //例外処理あり
            if ((epbMode & EPB_MODE_MC68882) != 0) {  //MC68882
              cirResponse = 0x8900_5608;  //PCを入力する→ダブルのデータを入力する→come-again
            } else {  //MC68881
              cirResponse = 0x8900_d608;  //PCを入力する→ダブルのデータを入力する→come-again
            }
            cirStage = CIR_PROGRAM_COUNTER;  //PC転送開始
          } else {
            if ((epbMode & EPB_MODE_MC68882) != 0) {  //MC68882
              cirResponse = 0x8900_1608;  //ダブルのデータを入力する→come-again
            } else {  //MC68881
              cirResponse = 0x8900_9608;  //ダブルのデータを入力する→come-again
            }
            cirOperandLength = 2;
            cirOperandIndex = 0;
            cirStage = CIR_SOURCE_OPERAND;  //ソースオペランド転送開始
          }
          return;
        }
        if (cirStage == CIR_PROGRAM_COUNTER) {  //PC転送終了
          cirOperandLength = 2;
          cirOperandIndex = 0;
          cirStage = CIR_SOURCE_OPERAND;  //ソースオペランド転送開始
          return;
        }
        if (cirStage == CIR_SOURCE_OPERAND) {  //ソースオペランド転送終了
          epbFPn[mmm = EPB_SRC_TMP].setd01 ((long) cirOperandBuffer[0] << 32 | cirOperandBuffer[1] & 0xffffffffL);
          if (cirPreInstruction ()) {
            return;
          }
        }
        break;

      case 0b110:  //$58xx-$5Bxx: Fop.B <ea>,FPn
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a 5800
        //    > cir 00 ...
        //    9501 8900 8900 
        //    > cir 10 01020304
        //    > cir 00 ..
        //    0802 0802 
        //    > cir 0a 6000
        //    > cir 00 ...
        //    8900 B104 0802 
        //    > cir 10 .
        //    00000001 
        //    > cir 00 ..
        //    0802 0802 
        //    --------------------------------
        if (cirStage == CIR_IDLE) {  //開始
          if ((epbFpcr & 0x0000ff00) != 0) {  //例外処理あり
            cirResponse = 0x8900_d501;  //バイトのデータを入力する→come-again
            cirStage = CIR_PROGRAM_COUNTER;  //PC転送開始
          } else {
            cirResponse = 0x8900_9501;  //バイトのデータを入力する→come-again
            cirOperandLength = 1;
            cirOperandIndex = 0;
            cirStage = CIR_SOURCE_OPERAND;  //ソースオペランド転送開始
          }
          return;
        }
        if (cirStage == CIR_PROGRAM_COUNTER) {  //PC転送終了
          cirOperandLength = 1;
          cirOperandIndex = 0;
          cirStage = CIR_SOURCE_OPERAND;  //ソースオペランド転送開始
          return;
        }
        if (cirStage == CIR_SOURCE_OPERAND) {  //ソースオペランド転送終了
          epbFPn[mmm = EPB_SRC_TMP].seti (cirOperandBuffer[0] >> 24);  //左詰めになっている
          if (cirPreInstruction ()) {
            return;
          }
        }
        break;

      case 0b111:  //$5Cxx-$5Fxx: FMOVECR.X #ccc,FPn
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a 5c00
        //    > cir 00 ..
        //    0900 0802 
        //    > cir 0a 6800
        //    > cir 00 ....
        //    8900 320C 8900 8900 
        //    > cir 10 .
        //    40000000 
        //    > cir 00 ..
        //    8900 8900 
        //    > cir 10 .
        //    C90FDAA2 
        //    > cir 00 ..
        //    0802 0802 
        //    > cir 10 .
        //    2168C235 
        //    > cir 00 ..
        //    0802 0802 
        //    --------------------------------
      default:
        if (0x40 <= ccccccc) {
          //マニュアルにはFMOVECRの命令フォーマットのROMオフセットが7bitあるように書かれているが実際は6bit
          //MC68882で0x40以上を指定すると命令実行前例外のF-line emulator(レスポンスプリミティブ0x1c0b)が返る
          cirException (0x1c0b);  //F-line emulator
          return;
        }
        if (false) {
          mmm = EPB_CONST_START + ccccccc;  //ソースオペランドをROMに変更する
          ccccccc = 0;  //命令をFMOVEに変更する
        } else {
          //FMOVECR
          epbFmovecr (epbFPn[nnn], ccccccc);
          if (cirMidInstruction ()) {
            return;
          }
          //終了
          cirIdle (0x0802);
          return;
        }

      }
      //Fop.X <ea>,FPn → Fop.X FP[EPB_SRC_TMP],FPn
      //FMOVECR.X #ccc,FPn → FMOVE.X FPc,FPn


      //fallthrough
    case 0b000:  //$0xxx-$1xxx: Fop.X FPm,FPn
      if (cirStage == CIR_IDLE) {  //開始
        epbFpsr &= 0x00ff00ff;
      }

      switch (ccccccc) {

      case 0b000_0000:  //$xx00: FMOVE.* *m,FPn
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a 4000
        //    > cir 00 ...
        //    9504 8900 8900 
        //    > cir 10 00000001
        //    > cir 00 ..
        //    0802 0802 
        //    > cir 0a 0000
        //    > cir 00 ...
        //    0900 0802 0802 
        //    --------------------------------
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  常にクリア
        //  OVFL   常にクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     常にクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbFPn[nnn].sete (epbFPn[mmm]).finish ();
        break;

      case 0b000_0001:  //$xx01: FINT.* *m,FPn
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a 4000
        //    > cir 00 ...
        //    9504 8900 8900 
        //    > cir 10 00000001
        //    > cir 00 ..
        //    0802 0802 
        //    > cir 0a 0001
        //    > cir 00 ...
        //    0900 0802 0802 
        //    --------------------------------
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  常にクリア
        //  OVFL   常にクリア
        //         正規化数の最大値は整数なので丸めても大きくなることはない
        //  UNFL   常にクリア
        //         結果は整数なので非正規化数にはならない
        //  DZ     常にクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        //  FINTはsingleとdoubleの丸め処理を行わない
        epbSetRoundingPrec (EPB_PREC_EXD);
        epbFPn[nnn].round (epbFPn[mmm], epbRoundingMode);
        break;

      case 0b000_0010:  //$xx02: FSINH.* *m,FPn
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a 4000
        //    > cir 00 ...
        //    9504 8900 8900 
        //    > cir 10 00000001
        //    > cir 00 ..
        //    0802 0802 
        //    > cir 0a 0002
        //    > cir 00 ...
        //    0900 0802 0802 
        //    --------------------------------
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  常にクリア
        //  OVFL   オーバーフローしたときセット、それ以外はクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     常にクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbFPn[nnn].sinh (epbFPn[mmm]);
        break;

      case 0b000_0011:  //$xx03: FINTRZ.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  常にクリア
        //  OVFL   常にクリア
        //  UNFL   常にクリア
        //         結果は整数なので非正規化数にはならない
        //  DZ     常にクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        //  FINTRZはsingleとdoubleの丸め処理を行わない
        epbSetRoundingPrec (EPB_PREC_EXD);
        epbFPn[nnn].trunc (epbFPn[mmm]);
        break;

      case 0b000_0100:  //$xx04: FSQRT.* *m,FPn
      case 0b000_0101:  //$xx05: FSQRT.* *m,FPn (MC68882)
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  引数が-0を除く負数のときセット、それ以外はクリア
        //  OVFL   常にクリア
        //         1よりも大きい数は小さくなるので溢れることはない
        //  UNFL   常にクリア
        //         非正規化数の平方根は正規化数なので結果が非正規化数になることはない
        //  DZ     常にクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbFPn[nnn].sqrt (epbFPn[mmm]);
        break;

      case 0b000_0110:  //$xx06: FLOGNP1.* *m,FPn
      case 0b000_0111:  //$xx07: FLOGNP1.* *m,FPn (MC68882)
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  引数が-1よりも小さいときセット、それ以外はクリア
        //  OVFL   常にクリア
        //         log(1+0)=0,log(1+x)<=xなので結果が引数よりも大きくなることはない
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     引数が-1のときセット、それ以外はクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbFPn[nnn].log1p (epbFPn[mmm]);
        break;

      case 0b000_1000:  //$xx08: FETOXM1.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  常にクリア
        //  OVFL   オーバーフローしたときセット、それ以外はクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     常にクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbFPn[nnn].expm1 (epbFPn[mmm]);
        break;

      case 0b000_1001:  //$xx09: FTANH.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  常にクリア
        //  OVFL   常にクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     常にクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbFPn[nnn].tanh (epbFPn[mmm]);
        break;

      case 0b000_1010:  //$xx0A: FATAN.* *m,FPn
      case 0b000_1011:  //$xx0B: FATAN.* *m,FPn (MC68882)
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  常にクリア
        //  OVFL   常にクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     常にクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbFPn[nnn].atan (epbFPn[mmm]);
        break;

      case 0b000_1100:  //$xx0C: FASIN.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  引数の絶対値が1よりも大きいときセット、それ以外はクリア
        //  OVFL   常にクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     常にクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbFPn[nnn].asin (epbFPn[mmm]);
        break;

      case 0b000_1101:  //$xx0D: FATANH.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  引数の絶対値が1よりも大きいときセット、それ以外はクリア
        //  OVFL   常にクリア
        //         1のとき無限大なのだから1の近くでオーバーフローしそうに思えるがatanh(1-2^-80)≒28.07くらい
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     引数の絶対値が1のときセット、それ以外はクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbFPn[nnn].atanh (epbFPn[mmm]);
        break;

      case 0b000_1110:  //$xx0E: FSIN.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  引数が無限大のときセット、それ以外はクリア
        //  OVFL   常にクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     常にクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbFPn[nnn].sin (epbFPn[mmm]);
        break;

      case 0b000_1111:  //$xx0F: FTAN.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  引数が無限大のときセット、それ以外はクリア
        //  OVFL   オーバーフローしたときセット、それ以外はクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     常にクリア
        //         cos(x)=0を満たすxは正確に表現できないのだからsin(x)/cos(x)がゼロ除算になるのはおかしい
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbFPn[nnn].tan (epbFPn[mmm]);
        break;

      case 0b001_0000:  //$xx10: FETOX.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  常にクリア
        //  OVFL   オーバーフローしたときセット、それ以外はクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     常にクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbFPn[nnn].exp (epbFPn[mmm]);
        break;

      case 0b001_0001:  //$xx11: FTWOTOX.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  常にクリア
        //  OVFL   オーバーフローしたときセット、それ以外はクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     常にクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbFPn[nnn].exp2 (epbFPn[mmm]);
        break;

      case 0b001_0010:  //$xx12: FTENTOX.* *m,FPn
      case 0b001_0011:  //$xx13: FTENTOX.* *m,FPn (MC68882)
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  常にクリア
        //  OVFL   オーバーフローしたときセット、それ以外はクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     常にクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbFPn[nnn].exp10 (epbFPn[mmm]);
        break;

      case 0b001_0100:  //$xx14: FLOGN.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  引数が0よりも小さいときセット、それ以外はクリア
        //  OVFL   常にクリア
        //         log(1)=0,log(x)<=x-1なので結果が引数よりも大きくなることはない
        //  UNFL   常にクリア
        //         log(1+2^-80)≒2^-80
        //  DZ     引数がゼロのときセット、それ以外はクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbFPn[nnn].log (epbFPn[mmm]);
        break;

      case 0b001_0101:  //$xx15: FLOG10.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  引数が0よりも小さいときセット、それ以外はクリア
        //  OVFL   常にクリア
        //  UNFL   常にクリア
        //  DZ     引数がゼロのときセット、それ以外はクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbFPn[nnn].log10 (epbFPn[mmm]);
        break;

      case 0b001_0110:  //$xx16: FLOG2.* *m,FPn
      case 0b001_0111:  //$xx17: FLOG2.* *m,FPn (MC68882)
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  引数が0よりも小さいときセット、それ以外はクリア
        //  OVFL   常にクリア
        //  UNFL   常にクリア
        //  DZ     引数がゼロのときセット、それ以外はクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbFPn[nnn].log2 (epbFPn[mmm]);
        break;

      case 0b001_1000:  //$xx18: FABS.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  常にクリア
        //  OVFL   常にクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     常にクリア
        //  INEX2  常にクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbFPn[nnn].abs (epbFPn[mmm]);
        break;

      case 0b001_1001:  //$xx19: FCOSH.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  常にクリア
        //  OVFL   オーバーフローしたときセット、それ以外はクリア
        //  UNFL   常にクリア
        //  DZ     常にクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbFPn[nnn].cosh (epbFPn[mmm]);
        break;

      case 0b001_1010:  //$xx1A: FNEG.* *m,FPn
      case 0b001_1011:  //$xx1B: FNEG.* *m,FPn (MC68882)
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  常にクリア
        //  OVFL   常にクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     常にクリア
        //  INEX2  常にクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbFPn[nnn].neg (epbFPn[mmm]);
        break;

      case 0b001_1100:  //$xx1C: FACOS.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  引数の絶対値が1よりも大きいときセット、それ以外はクリア
        //  OVFL   常にクリア
        //  UNFL   常にクリア
        //         acos(1-ulp(1))はulp(1)よりも大きい
        //  DZ     常にクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //         おそらくセットされないのはacos(1)=0だけ
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbFPn[nnn].acos (epbFPn[mmm]);
        break;

      case 0b001_1101:  //$xx1D: FCOS.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  引数が無限大のときセット、それ以外はクリア
        //  OVFL   常にクリア
        //  UNFL   常にクリア
        //         cos(x)=0を満たすxは正確に表現できず、cos(pi/2)とcos(3*pi/2)が正規化数になってしまう
        //  DZ     常にクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbFPn[nnn].cos (epbFPn[mmm]);
        break;

      case 0b001_1110:  //$xx1E: FGETEXP.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  引数が無限大のときセット、それ以外はクリア
        //  OVFL   常にクリア
        //  UNFL   常にクリア
        //  DZ     常にクリア
        //  INEX2  常にクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbFPn[nnn].getexp (epbFPn[mmm]);
        break;

      case 0b001_1111:  //$xx1F: FGETMAN.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  引数が無限大のときセット、それ以外はクリア
        //  OVFL   常にクリア
        //  UNFL   常にクリア
        //  DZ     常にクリア
        //  INEX2  常にクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbFPn[nnn].getman (epbFPn[mmm]);
        break;

      case 0b010_0000:  //$xx20: FDIV.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  引数が両方ゼロまたは両方無限大のときセット、それ以外はクリア
        //  OVFL   オーバーフローしたときセット、それ以外はクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     被除数がゼロ、無限大、NaN以外で除数がゼロのときセット、それ以外はクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbFPn[nnn].div (epbFPn[mmm]);
        break;

      case 0b010_0001:  //$xx21: FMOD.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  除数がゼロまたは被除数が無限大のときセット、それ以外はクリア
        //  OVFL   常にクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     常にクリア
        //         除数がゼロのとき結果は無限大ではなくNaNでありゼロ除算にはならない
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        //  FPSRのquotient byteに符号付き商の下位7bitが入る
        epbFPn[nnn].rem (epbFPn[mmm]);
        break;

      case 0b010_0010:  //$xx22: FADD.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  引数が両方無限大で符号が異なるときセット、それ以外はクリア
        //  OVFL   オーバーフローしたときセット、それ以外はクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     常にクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbFPn[nnn].add (epbFPn[mmm]);
        break;

      case 0b010_0011:  //$xx23: FMUL.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  引数の一方がゼロで他方が無限大のときセット、それ以外はクリア
        //  OVFL   オーバーフローしたときセット、それ以外はクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     常にクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbFPn[nnn].mul (epbFPn[mmm]);
        break;

      case 0b010_0100:  //$xx24: FSGLDIV.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  引数が両方ゼロまたは両方無限大のときセット、それ以外はクリア
        //  OVFL   オーバーフローしたときセット、それ以外はクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     被除数がゼロ、無限大、NaN以外で除数がゼロのときセット、それ以外はクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbSetRoundingPrec (EPB_PREC_XSG);
        epbFPn[nnn].div (epbFPn[mmm]);
        break;

      case 0b010_0101:  //$xx25: FREM.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  除数がゼロまたは被除数が無限大のときセット、それ以外はクリア
        //  OVFL   常にクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     常にクリア
        //         除数がゼロのとき結果は無限大ではなくNaNでありゼロ除算にはならない
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //         マニュアルにClearedと書いてあるのは間違い
        //         除数が無限大で被除数をそのまま返す場合でもサイズが減ればアンダーフローや不正確な結果になることはマニュアルにも書かれている
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        //  FPSRのquotient byteに符号付き商の下位7bitが入る
        epbFPn[nnn].ieeerem (epbFPn[mmm]);
        break;

      case 0b010_0110:  //$xx26: FSCALE.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  引数が無限大のときセット、それ以外はクリア
        //  OVFL   オーバーフローしたときセット、それ以外はクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     常にクリア
        //  INEX2  常にクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        //! 本来はソースが整数のとき浮動小数点数を経由しないが、これは経由してしまっている。結果は同じだが効率が悪い
        epbFPn[nnn].scale (epbFPn[mmm]);
        break;

      case 0b010_0111:  //$xx27: FSGLMUL.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  引数の一方がゼロで他方が無限大のときセット、それ以外はクリア
        //  OVFL   オーバーフローしたときセット、それ以外はクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     常にクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        {
          //引数を24bitに切り捨てるときX2をセットしない
          int sr = epbFpsr;
          epbFPn[EPB_SRC_TMP].roundmanf (epbFPn[mmm], EPB_MODE_RZ);
          epbFPn[EPB_DST_TMP].roundmanf (epbFPn[nnn], EPB_MODE_RZ);
          epbFpsr = sr;
        }
        epbSetRoundingPrec (EPB_PREC_XSG);
        epbFPn[nnn].mul (epbFPn[EPB_DST_TMP], epbFPn[EPB_SRC_TMP]);
        break;

      case 0b010_1000:  //$xx28: FSUB.* *m,FPn
      case 0b010_1001:  //$xx29: FSUB.* *m,FPn (MC68882)
      case 0b010_1010:  //$xx2A: FSUB.* *m,FPn (MC68882)
      case 0b010_1011:  //$xx2B: FSUB.* *m,FPn (MC68882)
      case 0b010_1100:  //$xx2C: FSUB.* *m,FPn (MC68882)
      case 0b010_1101:  //$xx2D: FSUB.* *m,FPn (MC68882)
      case 0b010_1110:  //$xx2E: FSUB.* *m,FPn (MC68882)
      case 0b010_1111:  //$xx2F: FSUB.* *m,FPn (MC68882)
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  引数が両方無限大で符号が同じときセット、それ以外はクリア
        //  OVFL   オーバーフローしたときセット、それ以外はクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     常にクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbFPn[nnn].sub (epbFPn[mmm]);
        break;

      case 0b011_0000:  //$xx30: FSINCOS.* *m,FP0:FPn (c=0,s=n)
      case 0b011_0001:  //$xx31: FSINCOS.* *m,FP1:FPn (c=1,s=n)
      case 0b011_0010:  //$xx32: FSINCOS.* *m,FP2:FPn (c=2,s=n)
      case 0b011_0011:  //$xx33: FSINCOS.* *m,FP3:FPn (c=3,s=n)
      case 0b011_0100:  //$xx34: FSINCOS.* *m,FP4:FPn (c=4,s=n)
      case 0b011_0101:  //$xx35: FSINCOS.* *m,FP5:FPn (c=5,s=n)
      case 0b011_0110:  //$xx36: FSINCOS.* *m,FP6:FPn (c=6,s=n)
      case 0b011_0111:  //$xx37: FSINCOS.* *m,FP7:FPn (c=7,s=n)
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  引数が無限大のときセット、それ以外はクリア
        //  OVFL   常にクリア
        //  UNFL   sin(x)の結果が非正規化数のときセット、それ以外はクリア
        //         cos(x)の結果は非正規化数にならない
        //  DZ     常にクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        {
          int ccc = ccccccc & 7;
          //mmm==EPB_SRC_TMP||mmm==nnn||mmm==cccの場合があることに注意する
          epbFPn[EPB_SRC_TMP].sete (epbFPn[mmm]);
          epbFPn[ccc].cos (epbFPn[EPB_SRC_TMP]);
          epbFPn[nnn].sin (epbFPn[EPB_SRC_TMP]);
        }
        break;

      case 0b011_1000:  //$xx38: FCMP.* *m,FPn
      case 0b011_1001:  //$xx39: FCMP.* *m,FPn (MC68882)
      case 0b011_1100:  //$xx3C: FCMP.* *m,FPn (MC68882)  コマンドワードの不連続箇所に注意
      case 0b011_1101:  //$xx3D: FCMP.* *m,FPn (MC68882)
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  常にクリア
        //  OVFL   常にクリア
        //  UNFL   常にクリア
        //  DZ     常にクリア
        //  INEX2  常にクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        //  FCMPはinfinityを常にクリアする
        //  efp.compareTo(x,y)を使う
        //    efp.compareTo(x,y)はefp.sub(x,y)よりも速い
        //    efp.sub(x,y)はINEX2をセットしてしまう
        //  efp.compareTo(x,y)は-0<+0だがFCMPは-0==+0なのでこれだけ調節する
        {
          int xf = epbFPn[nnn].flg;
          int yf = epbFPn[mmm].flg;
          if ((xf | yf) << 3 < 0) {  //どちらかがNaN
            //epbFPn[EPB_DST_TMP].setnan ();
            epbFPn[EPB_DST_TMP].flg = N;
          } else {
            int i = ((xf & yf) << 1 < 0 ? 0 :  //両方±0
                     epbFPn[nnn].compareTo (epbFPn[mmm]));  //-Inf==-Inf<-x<-0<+0<+x<+Inf==+Inf<NaN==NaN
            if (i == 0) {
              if (xf < 0) {
                //epbFPn[EPB_DST_TMP].negset0 ();
                epbFPn[EPB_DST_TMP].flg = M | Z;
              } else {
                //epbFPn[EPB_DST_TMP].set0 ();
                epbFPn[EPB_DST_TMP].flg = P | Z;
              }
            } else if (i < 0) {
              epbFPn[EPB_DST_TMP].negset1 ();
            } else {
              epbFPn[EPB_DST_TMP].set1 ();
            }
          }
          nnn = EPB_DST_TMP;
        }
        break;

      case 0b011_1010:  //$xx3A: FTST.* *m
      case 0b011_1011:  //$xx3B: FTST.* *m (MC68882)
      case 0b011_1110:  //$xx3E: FTST.* *m (MC68882)  コマンドワードの不連続箇所に注意
      case 0b011_1111:  //$xx3F: FTST.* *m (MC68882)
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  常にクリア
        //  OVFL   常にクリア
        //  UNFL   常にクリア
        //  DZ     常にクリア
        //  INEX2  常にクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        //  ソースオペランドをダミーのデスティネーションオペランドにコピーしてテストする
        //  デスティネーションオペランドは変化しない
        //  デスティネーションオペランドにはFP0が指定される場合が多いがFP0である必要はない
        epbFPn[EPB_DST_TMP].sete (epbFPn[mmm]);
        nnn = EPB_DST_TMP;
        break;

      case 0b100_0000:  //$xx40: FSMOVE.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  常にクリア
        //  OVFL   常にクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     常にクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbSetRoundingPrec (EPB_PREC_SGL);
        epbFPn[nnn].sete (epbFPn[mmm]).finish ();
        break;

      case 0b100_0001:  //$xx41: FSSQRT.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  引数が-0を除く負数のときセット、それ以外はクリア
        //  OVFL   常にクリア
        //  UNFL   常にクリア
        //  DZ     常にクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbSetRoundingPrec (EPB_PREC_SGL);
        epbFPn[nnn].sqrt (epbFPn[mmm]);
        break;

        //case 0b100_0010:  //$xx42:
        //case 0b100_0011:  //$xx43:

      case 0b100_0100:  //$xx44: FDMOVE.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  常にクリア
        //  OVFL   常にクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     常にクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbSetRoundingPrec (EPB_PREC_DBL);
        epbFPn[nnn].sete (epbFPn[mmm]).finish ();
        break;

      case 0b100_0101:  //$xx45: FDSQRT.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  引数が-0を除く負数のときセット、それ以外はクリア
        //  OVFL   常にクリア
        //  UNFL   常にクリア
        //  DZ     常にクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbSetRoundingPrec (EPB_PREC_DBL);
        epbFPn[nnn].sqrt (epbFPn[mmm]);
        break;

        //case 0b100_0110:  //$xx46:
        //case 0b100_0111:  //$xx47:
        //case 0b100_1000:  //$xx48:
        //case 0b100_1001:  //$xx49:
        //case 0b100_1010:  //$xx4A:
        //case 0b100_1011:  //$xx4B:
        //case 0b100_1100:  //$xx4C:
        //case 0b100_1101:  //$xx4D:
        //case 0b100_1110:  //$xx4E:
        //case 0b100_1111:  //$xx4F:
        //case 0b101_0000:  //$xx50:
        //case 0b101_0001:  //$xx51:
        //case 0b101_0010:  //$xx52:
        //case 0b101_0011:  //$xx53:
        //case 0b101_0100:  //$xx54:
        //case 0b101_0101:  //$xx55:
        //case 0b101_0110:  //$xx56:
        //case 0b101_0111:  //$xx57:

      case 0b101_1000:  //$xx58: FSABS.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  常にクリア
        //  OVFL   常にクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     常にクリア
        //  INEX2  常にクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbSetRoundingPrec (EPB_PREC_SGL);
        epbFPn[nnn].abs (epbFPn[mmm]);
        break;

        //case 0b101_1001:  //$xx59:

      case 0b101_1010:  //$xx5A: FSNEG.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  常にクリア
        //  OVFL   常にクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     常にクリア
        //  INEX2  常にクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbSetRoundingPrec (EPB_PREC_SGL);
        epbFPn[nnn].neg (epbFPn[mmm]);
        break;

        //case 0b101_1011:  //$xx5B:

      case 0b101_1100:  //$xx5C: FDABS.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  常にクリア
        //  OVFL   常にクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     常にクリア
        //  INEX2  常にクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbSetRoundingPrec (EPB_PREC_DBL);
        epbFPn[nnn].abs (epbFPn[mmm]);
        break;

        //case 0b101_1101:  //$xx5D:

      case 0b101_1110:  //$xx5E: FDNEG.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  常にクリア
        //  OVFL   常にクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     常にクリア
        //  INEX2  常にクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbSetRoundingPrec (EPB_PREC_DBL);
        epbFPn[nnn].neg (epbFPn[mmm]);
        break;

        //case 0b101_1111:  //$xx5F:

      case 0b110_0000:  //$xx60: FSDIV.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  引数が両方ゼロまたは両方無限大のときセット、それ以外はクリア
        //  OVFL   オーバーフローしたときセット、それ以外はクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     被除数がゼロ、無限大、NaN以外で除数がゼロのときセット、それ以外はクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbSetRoundingPrec (EPB_PREC_SGL);
        epbFPn[nnn].div (epbFPn[mmm]);
        break;

        //case 0b110_0001:  //$xx61:

      case 0b110_0010:  //$xx62: FSADD.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  引数が両方無限大で符号が異なるときセット、それ以外はクリア
        //  OVFL   オーバーフローしたときセット、それ以外はクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     常にクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbSetRoundingPrec (EPB_PREC_SGL);
        epbFPn[nnn].add (epbFPn[mmm]);
        break;

      case 0b110_0011:  //$xx63: FSMUL.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  引数の一方がゼロで他方が無限大のときセット、それ以外はクリア
        //  OVFL   オーバーフローしたときセット、それ以外はクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     常にクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbSetRoundingPrec (EPB_PREC_SGL);
        epbFPn[nnn].mul (epbFPn[mmm]);
        break;

      case 0b110_0100:  //$xx64: FDDIV.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  引数が両方ゼロまたは両方無限大のときセット、それ以外はクリア
        //  OVFL   オーバーフローしたときセット、それ以外はクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     被除数がゼロ、無限大、NaN以外で除数がゼロのときセット、それ以外はクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbSetRoundingPrec (EPB_PREC_DBL);
        epbFPn[nnn].div (epbFPn[mmm]);
        break;

        //case 0b110_0101:  //$xx65:

      case 0b110_0110:  //$xx66: FDADD.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  引数が両方無限大で符号が異なるときセット、それ以外はクリア
        //  OVFL   オーバーフローしたときセット、それ以外はクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     常にクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbSetRoundingPrec (EPB_PREC_DBL);
        epbFPn[nnn].add (epbFPn[mmm]);
        break;

      case 0b110_0111:  //$xx67: FDMUL.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  引数の一方がゼロで他方が無限大のときセット、それ以外はクリア
        //  OVFL   オーバーフローしたときセット、それ以外はクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     常にクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbSetRoundingPrec (EPB_PREC_DBL);
        epbFPn[nnn].mul (epbFPn[mmm]);
        break;

      case 0b110_1000:  //$xx68: FSSUB.* *m,FPn
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  引数が両方無限大で符号が同じときセット、それ以外はクリア
        //  OVFL   オーバーフローしたときセット、それ以外はクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     常にクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbSetRoundingPrec (EPB_PREC_SGL);
        epbFPn[nnn].sub (epbFPn[mmm]);
        break;

        //case 0b110_1001:  //$xx69:
        //case 0b110_1010:  //$xx6A:
        //case 0b110_1011:  //$xx6B:

      case 0b110_1100:  //$xx6C: FDSUB.* *m,FPn
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a 4000
        //    > cir 00 ...
        //    9504 8900 8900 
        //    > cir 10 00000001
        //    > cir 00 ..
        //    0802 0802 
        //    > cir 0a 006c
        //    > cir 00 ...
        //    1C0B 1C0B 1C0B 
        //    > cir 02 0000
        //    > cir 00 ...
        //    0802 0802 0802 
        //    --------------------------------
        //  BSUN   常にクリア
        //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
        //  OPERR  引数が両方無限大で符号が同じときセット、それ以外はクリア
        //  OVFL   オーバーフローしたときセット、それ以外はクリア
        //  UNFL   結果が非正規化数のときセット、それ以外はクリア
        //  DZ     常にクリア
        //  INEX2  結果に誤差があるときセット、それ以外はクリア
        //  INEX1  引数がpackedで正確に変換できないときセット、それ以外はクリア
        epbSetRoundingPrec (EPB_PREC_DBL);
        epbFPn[nnn].sub (epbFPn[mmm]);
        break;

        //case 0b110_1101:  //$xx6D:
        //case 0b110_1110:  //$xx6E:
        //case 0b110_1111:  //$xx6F:

      case 0b111_0000:  //$xx70: FLGAMMA *m,FPn
        if (EFPBox.EPB_EXTRA_OPERATION) {
          epbFPn[nnn].lgamma (epbFPn[mmm]);
        } else {
          cirException (0x1c0b);  //F-line emulator
        }
        break;

      case 0b111_0001:  //$xx71: FTGAMMA *m,FPn
        if (EFPBox.EPB_EXTRA_OPERATION) {
          epbFPn[nnn].tgamma (epbFPn[mmm]);
        } else {
          cirException (0x1c0b);  //F-line emulator
        }
        break;

        //case 0b111_0010:  //$xx72:
        //case 0b111_0011:  //$xx73:
        //case 0b111_0100:  //$xx74:
        //case 0b111_0101:  //$xx75:
        //case 0b111_0110:  //$xx76:
        //case 0b111_0111:  //$xx77:
        //case 0b111_1000:  //$xx78:
        //case 0b111_1001:  //$xx79:
        //case 0b111_1010:  //$xx7A:
        //case 0b111_1011:  //$xx7B:
        //case 0b111_1100:  //$xx7C:
        //case 0b111_1101:  //$xx7D:
        //case 0b111_1110:  //$xx7E:
        //case 0b111_1111:  //$xx7F:

      default:  //未定義
        cirException (0x1c0b);  //F-line emulator
        return;
      }
      //FPSRのFPCCを設定する
      epbFpsr |= epbFPn[nnn].flg >>> 4;
      if (cirMidInstruction ()) {
        return;
      }
      //終了
      cirIdle (0x0802);
      return;


    case 0b011:  //$6xxx-$7xxx: FMOVE.* FPn,<ea>
      //  BSUN   常にクリア
      //  SNAN   引数がシグナリングNaNのときセット、それ以外はクリア
      //  OPERR  byte,word,longで無限大または指定されたサイズに収まらないとき、packedでk-factorが17よりも大きいか指数部が3桁に収まらないときセット、それ以外はクリア
      //  OVFL   packedではなくてオーバーフローしたときセット、それ以外はクリア
      //  UNFL   packedではなくて結果が非正規化数のときセット、それ以外はクリア
      //  DZ     常にクリア
      //  INEX2  結果に誤差があるときセット、それ以外はクリア
      //  INEX1  常にクリア
      if (cirStage == CIR_IDLE) {  //開始
        epbFpsr &= 0xffff00ff;  //FMOVE.* FPn,<ea>でFPSRのコンディションコードバイトは変化しない
      } else if (cirStage == CIR_DESTINATION_OPERAND) {  //デスティネーションオペランド転送終了
        //終了
        cirIdle (0x0802);
        return;
      }

      switch (mmm) {

      case 0b000:  //$60xx-$63xx: FMOVE.L FPn,<ea>
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a 4000
        //    > cir 00 ...
        //    9504 8900 8900 
        //    > cir 10 00000001
        //    > cir 00 .
        //    0802 
        //    > cir 0a 6000
        //    > cir 00 ...
        //    8900 B104 0802 
        //    > cir 10 .
        //    00000001 
        //    > cir 00 ..
        //    0802 0802 
        //    --------------------------------
        cirOperandBuffer[0] = epbFPn[nnn].geti (epbRoundingMode);
        if (cirMidInstruction ()) {
          return;
        }
        cirResponse = 0x8900_b104;  //(come-again→)ロングのデータを出力する→come-again
        cirOperandLength = 1;
        cirOperandIndex = 0;
        cirStage = CIR_DESTINATION_OPERAND;  //デスティネーションオペランド転送開始
        break;

      case 0b001:  //$64xx-$67xx: FMOVE.S FPn,<ea>
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a 4000
        //    > cir 00 ...
        //    9504 8900 8900 
        //    > cir 10 00000001
        //    > cir 00 .
        //    0802 
        //    > cir 0a 6400
        //    > cir 00 ....
        //    8900 3104 0802 0802 
        //    > cir 10 .
        //    3F800000 
        //    > cir 00 ..
        //    0802 0802 
        //    --------------------------------
        cirOperandBuffer[0] = epbFPn[nnn].getf0 (epbRoundingMode);
        if (cirMidInstruction ()) {
          return;
        }
        if ((epbMode & EPB_MODE_MC68882) != 0) {  //MC68882
          cirResponse = 0x8900_3104;  //(come-again→)ロングのデータを出力する→come-again
        } else {  //MC68881
          cirResponse = 0x8900_b104;  //(come-again→)ロングのデータを出力する→come-again
        }
        cirOperandLength = 1;
        cirOperandIndex = 0;
        cirStage = CIR_DESTINATION_OPERAND;  //デスティネーションオペランド転送開始
        break;

      case 0b010:  //$68xx-$6Bxx: FMOVE.X FPn,<ea>
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a 4000
        //    > cir 00 ...
        //    9504 8900 8900 
        //    > cir 10 00000001
        //    > cir 00 .
        //    0802 
        //    > cir 0a 6800
        //    > cir 00 ....
        //    8900 320C 8900 8900 
        //    > cir 10 .
        //    3FFF0000 
        //    > cir 00 ..
        //    8900 8900 
        //    > cir 10 .
        //    80000000 
        //    > cir 00 ..
        //    0802 0802 
        //    > cir 10 .
        //    00000000 
        //    > cir 00 ..
        //    0802 0802 
        //    --------------------------------
        {
          byte[] b = new byte[12];
          if (epbIsTriple ()) {  //三倍精度
            epbFPn[nnn].gety012 (b, 0, epbRoundingMode);
          } else {  //拡張精度
            epbFPn[nnn].getx012 (b, 0, epbRoundingMode);
          }
          if (cirMidInstruction ()) {
            return;
          }
          cirOperandBuffer[0] = b[0] << 24 | (b[1] & 255) << 16 | (char) (b[2] << 8 | b[3] & 255);
          cirOperandBuffer[1] = b[4] << 24 | (b[5] & 255) << 16 | (char) (b[6] << 8 | b[7] & 255);
          cirOperandBuffer[2] = b[8] << 24 | (b[9] & 255) << 16 | (char) (b[10] << 8 | b[11] & 255);
          if ((epbMode & EPB_MODE_MC68882) != 0) {  //MC68882
            cirResponse = 0x8900_320c;  //(come-again→)エクステンデッドのデータを出力する→come-again
          } else {  //MC68881
            cirResponse = 0x8900_320c;  //(come-again→)エクステンデッドのデータを出力する→come-again
          }
          cirOperandLength = 3;
          cirOperandIndex = 0;
          cirStage = CIR_DESTINATION_OPERAND;  //デスティネーションオペランド転送開始
          break;
        }

      case 0b011:  //$6Cxx-$6Fxx: FMOVE.P FPn,<ea>{#k}
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a 4000
        //    > cir 00 ...
        //    9504 8900 8900 
        //    > cir 10 00000001
        //    > cir 00 .
        //    0802 
        //    > cir 0a 6c00
        //    > cir 00 ....
        //    8900 B20C 8900 8900 
        //    > cir 10 .
        //    00000001 
        //    > cir 00 ..
        //    8900 8900 
        //    > cir 10 .
        //    00000000 
        //    > cir 00 ..
        //    0802 0802 
        //    > cir 10 .
        //    00000000 
        //    > cir 00 ..
        //    0802 0802 
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a 5c00
        //    > cir 00 ..
        //    0900 0802 
        //    > cir 0a 6c7e
        //    > cir 00 ....
        //    8900 B20C 8900 8900 
        //    > cir 10 ...
        //    00000003 14000000 00000000 
        //    > cir 00 ..
        //    0802 0802 
        //    > cir 0a 6c7f
        //    > cir 00 ....
        //    8900 B20C 8900 8900 
        //    > cir 10 ...
        //    00000003 10000000 00000000 
        //    > cir 00 ..
        //    0802 0802 
        //    > cir 0a 6c00
        //    > cir 00 ....
        //    8900 B20C 8900 8900 
        //    > cir 10 ...
        //    00000003 00000000 00000000 
        //    > cir 00 ..
        //    0802 0802 
        //    > cir 0a 6c01
        //    > cir 00 ....
        //    8900 B20C 8900 8900 
        //    > cir 10 ...
        //    00000003 00000000 00000000 
        //    > cir 00 ..
        //    0802 0802 
        //    > cir 0a 6c02
        //    > cir 00 ....
        //    8900 B20C 8900 8900 
        //    > cir 10 ...
        //    00000003 10000000 00000000 
        //    > cir 00 ..
        //    0802 0802 
        //    > cir 0a 6c03
        //    > cir 00 ....
        //    8900 B20C 8900 8900 
        //    > cir 10 ...
        //    00000003 14000000 00000000 
        //    > cir 00 ..
        //    0802 0802 
        //    > cir 0a 6c04
        //    > cir 00 ....
        //    8900 B20C 8900 8900 
        //    > cir 10 ...
        //    00000003 14200000 00000000 
        //    > cir 00 ..
        //    0802 0802 
        //    > cir 0a 6c05
        //    > cir 00 ....
        //    8900 B20C 8900 8900 
        //    > cir 10 ...
        //    00000003 14160000 00000000 
        //    > cir 00 ..
        //    0802 0802 
        //    > cir 0a 6c7d
        //    > cir 00 ....
        //    8900 B20C 8900 8900 
        //    > cir 10 ...
        //    00000003 14200000 00000000 
        //    > cir 00 ..
        //    0802 0802 
        //    > cir 0a 6c7c
        //    > cir 00 ....
        //    8900 B20C 8900 8900 
        //    > cir 10 ...
        //    00000003 14160000 00000000 
        //    > cir 00 ..
        //    0802 0802 
        //    --------------------------------
        {
          byte[] b = new byte[12];
          epbFPn[nnn].getp012 (b, 0, ccccccc);  //k-factor付き
          if (cirMidInstruction ()) {
            return;
          }
          cirOperandBuffer[0] = b[0] << 24 | (b[1] & 255) << 16 | (char) (b[2] << 8 | b[3] & 255);
          cirOperandBuffer[1] = b[4] << 24 | (b[5] & 255) << 16 | (char) (b[6] << 8 | b[7] & 255);
          cirOperandBuffer[2] = b[8] << 24 | (b[9] & 255) << 16 | (char) (b[10] << 8 | b[11] & 255);
          cirResponse = 0x8900_b20c;  //(come-again→)パックトのデータを出力する→come-again
          cirOperandLength = 3;
          cirOperandIndex = 0;
          cirStage = CIR_DESTINATION_OPERAND;  //デスティネーションオペランド転送開始
          break;
        }

      case 0b100:  //$70xx-$73xx: FMOVE.W FPn,<ea>
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a 4000
        //    > cir 00 ...
        //    9504 8900 8900 
        //    > cir 10 00000001
        //    > cir 00 .
        //    0802 
        //    > cir 0a 7000
        //    > cir 00 ....
        //    8900 B102 0802 0802 
        //    > cir 10 .
        //    00010000 
        //    > cir 00 ..
        //    0802 0802 
        //    --------------------------------
        cirOperandBuffer[0] = epbFPn[nnn].gets (epbRoundingMode) << 16;  //左詰めにする
        if (cirMidInstruction ()) {
          return;
        }
        cirResponse = 0x8900_b102;  //(come-again→)ワードのデータを出力する→come-again
        cirOperandLength = 1;
        cirOperandIndex = 0;
        cirStage = CIR_DESTINATION_OPERAND;  //デスティネーションオペランド転送開始
        break;

      case 0b101:  //$74xx-$77xx: FMOVE.D FPn,<ea>
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a 4000
        //    > cir 00 ...
        //    9504 8900 8900 
        //    > cir 10 00000001
        //    > cir 00 .
        //    0802 
        //    > cir 0a 7400
        //    > cir 00 ....
        //    8900 3208 8900 8900 
        //    > cir 10 .
        //    3FF00000 
        //    > cir 00 ..
        //    0802 0802 
        //    > cir 10 .
        //    00000000 
        //    > cir 00 ..
        //    0802 0802 
        //    --------------------------------
        {
          long l = epbFPn[nnn].getd01 (epbRoundingMode);
          if (cirMidInstruction ()) {
            return;
          }
          cirOperandBuffer[0] = (int) (l >> 32);
          cirOperandBuffer[1] = (int) l;
          if ((epbMode & EPB_MODE_MC68882) != 0) {  //MC68882
            cirResponse = 0x8900_3208;  //(come-again→)ダブルのデータを出力する→come-again
          } else {
            cirResponse = 0x8900_b208;  //(come-again→)ダブルのデータを出力する→come-again
          }
          cirOperandLength = 2;
          cirOperandIndex = 0;
          cirStage = CIR_DESTINATION_OPERAND;  //デスティネーションオペランド転送開始
        }
        break;

      case 0b110:  //$78xx-$7Bxx: FMOVE.B FPn,<ea>
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a 4000
        //    > cir 00 ....
        //    9504 8900 8900 8900 
        //    > cir 10 00000001
        //    > cir 00 .
        //    0802 
        //    > cir 0a 7800
        //    > cir 00 ....
        //    8900 B101 0802 0802 
        //    > cir 10 .
        //    01000000 
        //    > cir 00 ..
        //    0802 0802 
        //    --------------------------------
        cirOperandBuffer[0] = epbFPn[nnn].getb (epbRoundingMode) << 24;  //左詰めにする
        if (cirMidInstruction ()) {
          return;
        }
        cirResponse = 0x8900_b101;  //(come-again→)バイトのデータを出力する→come-again
        cirOperandLength = 1;
        cirOperandIndex = 0;
        cirStage = CIR_DESTINATION_OPERAND;  //デスティネーションオペランド転送開始
        break;

      case 0b111:  //$7Cxx-$7Fxx: FMOVE.P FPn,<ea>{Dl}
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a 4000
        //    > cir 00 ...
        //    9504 8900 8900 
        //    > cir 10 00000100
        //    > cir 00 .
        //    0802 
        //    > cir 0a 7c00
        //    > cir 00 ....
        //    8C00 8900 8900 8900 
        //    > cir 10 00000005
        //    > cir 00 ...
        //    B20C 8900 8900 
        //    > cir 10 .
        //    00020002 
        //    > cir 00 ..
        //    8900 8900 
        //    > cir 10 .
        //    56000000 
        //    > cir 00 ..
        //    0802 0802 
        //    > cir 10 .
        //    00000000 
        //    > cir 00 ..
        //    0802 0802 
        //    --------------------------------
      default:
        if (cirStage == CIR_IDLE) {  //開始
          cirResponse = 0x8900_8c00 + (cirCommand >> 4 & 7);  //データレジスタを入力する→come-again
          cirOperandLength = 1;
          cirOperandIndex = 0;
          cirStage = CIR_DYNAMIC_K_FACTOR;  //動的k-factor転送開始
          return;
        } else if (cirStage == CIR_DYNAMIC_K_FACTOR) {  //動的k-factor転送終了
          byte[] b = new byte[12];
          epbFPn[nnn].getp012 (b, 0, cirOperandBuffer[0]);  //k-factor付き
          if (cirMidInstruction ()) {
            return;
          }
          cirOperandBuffer[0] = b[0] << 24 | (b[1] & 255) << 16 | (char) (b[2] << 8 | b[3] & 255);
          cirOperandBuffer[1] = b[4] << 24 | (b[5] & 255) << 16 | (char) (b[6] << 8 | b[7] & 255);
          cirOperandBuffer[2] = b[8] << 24 | (b[9] & 255) << 16 | (char) (b[10] << 8 | b[11] & 255);
          cirResponse = 0x8900_b20c;  //(come-again→)パックトのデータを出力する→come-again
          cirOperandLength = 3;
          cirOperandIndex = 0;
          cirStage = CIR_DESTINATION_OPERAND;  //デスティネーションオペランド転送開始
        }
      }
      return;


    case 0b100:  //$8xxx-$9xxx: FMOVEM.L <ea>,FPCR/FPSR/FPIAR
      //  FMOVEM命令は例外を発生させずFPCR/FPSR/FPIARも(デスティネーションに書かれたもの以外)変化しない
      //  格納順序はFPCRが下位アドレス(連結したとき上位),FPIARが上位アドレス(連結したとき下位)

      switch (mmm) {

      case 0b000:  //$8000: FMOVE.L <ea>,<>
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a 8000
        //    > cir 00 ....
        //    8900 9704 8900 8900 
        //    > cir 10 00000000
        //    > cir 00 ..
        //    0802 0802 
        //    --------------------------------
        //  レジスタを1個も指定しないとFPIARが指定されたものとみなされる

      case 0b001:  //$8400: FMOVE.L <ea>,FPIAR
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a 8400
        //    > cir 00 ....
        //    8900 9704 8900 8900 
        //    > cir 10 00000000
        //    > cir 00 ..
        //    0802 0802 
        //    --------------------------------
        if (cirStage == CIR_IDLE) {  //開始
          cirResponse = 0x8900_9704;  //FPIARを入力する→come_again
          cirOperandLength = 1;
          cirOperandIndex = 0;
          cirStage = CIR_SOURCE_OPERAND;  //ソースオペランド転送開始
          return;
        } else {  //ソースオペランド転送終了
          epbFpiar = cirOperandBuffer[0];
        }
        break;

      case 0b010:  //$8800: FMOVE.L <ea>,FPSR
        //  fmove.lでfpsrのEXCに書き込んだだけではAEXCは更新されない
        //  fmove.lでfpsrに0x0000ff00を書き込んですぐに読み出しても0x0000ff00のまま
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a 8800
        //    > cir 00 ....
        //    8900 9504 8900 8900 
        //    > cir 10 00000000
        //    > cir 00 ..
        //    0802 0802 
        //    --------------------------------
        if (cirStage == CIR_IDLE) {  //開始
          cirResponse = 0x8900_9504;  //FPSRを入力する→come_again
          cirOperandLength = 1;
          cirOperandIndex = 0;
          cirStage = CIR_SOURCE_OPERAND;  //ソースオペランド転送開始
          return;
        } else {  //ソースオペランド転送終了
          epbFpsr = cirOperandBuffer[0] & EPB_FPSR_ALL;
        }
        break;

      case 0b011:  //$8C00: FMOVEM.L <ea>,FPSR/FPIAR
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a 8c00
        //    > cir 00 ....
        //    8900 9608 8900 8900 
        //    > cir 10 00000000
        //    > cir 00 ..
        //    8900 8900 
        //    > cir 10 00000000
        //    > cir 00 ..
        //    0802 0802 
        //    --------------------------------
        if (cirStage == CIR_IDLE) {  //開始
          cirResponse = 0x8900_9608;  //FPSR/FPIARを入力する→come_again
          cirOperandLength = 2;
          cirOperandIndex = 0;
          cirStage = CIR_SOURCE_OPERAND;  //ソースオペランド転送開始
          return;
        } else {  //ソースオペランド転送終了
          epbFpsr = cirOperandBuffer[0] & EPB_FPSR_ALL;
          epbFpiar = cirOperandBuffer[1];
        }
        break;

      case 0b100:  //$9000: FMOVE.L <ea>,FPCR
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a 9000
        //    > cir 00 ....
        //    8900 9504 8900 8900 
        //    > cir 10 00000000
        //    > cir 00 ..
        //    0802 0802 
        //    --------------------------------
        if (cirStage == CIR_IDLE) {  //開始
          cirResponse = 0x8900_9504;  //FPCRを入力する→come_again
          cirOperandLength = 1;
          cirOperandIndex = 0;
          cirStage = CIR_SOURCE_OPERAND;  //ソースオペランド転送開始
          return;
        } else {  //ソースオペランド転送終了
          epbFpcr = cirOperandBuffer[0] & EPB_FPCR_ALL;
        }
        break;

      case 0b101:  //$9400: FMOVEM.L <ea>,FPCR/FPIAR
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a 9400
        //    > cir 00 ....
        //    8900 9608 8900 8900 
        //    > cir 10 00000000
        //    > cir 00 ..
        //    8900 8900 
        //    > cir 10 00000000
        //    > cir 00 ..
        //    0802 0802 
        //    --------------------------------
        if (cirStage == CIR_IDLE) {  //開始
          cirResponse = 0x8900_9608;  //FPCR/FPIARを入力する→come_again
          cirOperandLength = 2;
          cirOperandIndex = 0;
          cirStage = CIR_SOURCE_OPERAND;  //ソースオペランド転送開始
          return;
        } else {  //ソースオペランド転送終了
          epbFpcr = cirOperandBuffer[0] & EPB_FPCR_ALL;
          epbFpiar = cirOperandBuffer[1];
        }
        break;

      case 0b110:  //$9800: FMOVEM.L <ea>,FPCR/FPSR
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a 9800
        //    > cir 00 ....
        //    8900 9608 8900 8900 
        //    > cir 10 00000000
        //    > cir 00 ..
        //    8900 8900 
        //    > cir 10 00000000
        //    > cir 00 ..
        //    0802 0802 
        //    --------------------------------
        if (cirStage == CIR_IDLE) {  //開始
          cirResponse = 0x8900_9608;  //FPCR/FPSRを入力する→come_again
          cirOperandLength = 2;
          cirOperandIndex = 0;
          cirStage = CIR_SOURCE_OPERAND;  //ソースオペランド転送開始
          return;
        } else {  //ソースオペランド転送終了
          epbFpcr = cirOperandBuffer[0] & EPB_FPCR_ALL;
          epbFpsr = cirOperandBuffer[1] & EPB_FPSR_ALL;
        }
        break;

      case 0b111:  //$9C00: FMOVEM.L <ea>,FPCR/FPSR/FPIAR
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a 9c00
        //    > cir 00 ....
        //    8900 960C 8900 8900 
        //    > cir 10 00000000
        //    > cir 00 ..
        //    8900 8900 
        //    > cir 10 00000000
        //    > cir 00 ..
        //    8900 8900 
        //    > cir 10 00000000
        //    > cir 00 ..
        //    0802 0802 
        //    --------------------------------
      default:
        if (cirStage == CIR_IDLE) {  //開始
          cirResponse = 0x8900_960c;  //FPCR/FPSR/FPIARを入力する→come_again
          cirOperandLength = 3;
          cirOperandIndex = 0;
          cirStage = CIR_SOURCE_OPERAND;  //ソースオペランド転送開始
          return;
        } else {  //ソースオペランド転送終了
          epbFpcr = cirOperandBuffer[0] & EPB_FPCR_ALL;
          epbFpsr = cirOperandBuffer[1] & EPB_FPSR_ALL;
          epbFpiar = cirOperandBuffer[2];
        }
      }
      //終了
      cirIdle (0x0802);
      return;


    case 0b101:  //$Axxx-$Bxxx: FMOVEM.L FPCR/FPSR/FPIAR,<ea>
      //  FMOVEM命令は例外を発生させずFPCR/FPSR/FPIARも(デスティネーションに書かれたもの以外)変化しない
      //  格納順序はFPCRが下位アドレス(連結したとき上位),FPIARが上位アドレス(連結したとき下位)
      if (cirStage == CIR_DESTINATION_OPERAND) {  //デスティネーションオペランド転送終了
        //終了
        cirIdle (0x0802);
        return;
      }

      switch (mmm) {

      case 0b000:  //$A000: FMOVE.L <>,<ea>
        //  レジスタを1個も指定しないとFPIARが指定されたものとみなされる
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a a000
        //    > cir 00 ....
        //    8900 B304 0802 0802 
        //    > cir 10 .
        //    00000000 
        //    > cir 00 ..
        //    0802 0802 
        //    --------------------------------

      case 0b001:  //$A400: FMOVE.L FPIAR,<ea>
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a a400
        //    > cir 00 ....
        //    8900 B304 0802 0802 
        //    > cir 10 .
        //    00000000 
        //    > cir 00 ..
        //    0802 0802 
        //    --------------------------------
        cirOperandBuffer[0] = epbFpiar;
        cirResponse = 0x8900_b304;  //FPIARを出力する→come_again
        cirOperandLength = 1;
        cirOperandIndex = 0;
        cirStage = CIR_DESTINATION_OPERAND;  //デスティネーションオペランド転送開始
        return;

      case 0b010:  //$A800: FMOVE.L FPSR,<ea>
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a a800
        //    > cir 00 ....
        //    8900 B104 0802 0802 
        //    > cir 10 .
        //    00000000 
        //    > cir 00 ..
        //    0802 0802 
        //    --------------------------------
        cirOperandBuffer[0] = epbFpsr;
        cirResponse = 0x8900_b104;  //FPSRを出力する→come_again
        cirOperandLength = 1;
        cirOperandIndex = 0;
        cirStage = CIR_DESTINATION_OPERAND;  //デスティネーションオペランド転送開始
        return;

      case 0b011:  //$AC00: FMOVEM.L FPSR/FPIAR,<ea>
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a ac00
        //    > cir 00 ....
        //    8900 B208 8900 8900 
        //    > cir 10 .
        //    00000000 
        //    > cir 00 ..
        //    0802 0802 
        //    > cir 10 .
        //    00000000 
        //    > cir 00 ..
        //    0802 0802 
        //    --------------------------------
        cirOperandBuffer[0] = epbFpsr;
        cirOperandBuffer[1] = epbFpiar;
        cirResponse = 0x8900_b208;  //FPSR/FPIARを出力する→come_again
        cirOperandLength = 2;
        cirOperandIndex = 0;
        cirStage = CIR_DESTINATION_OPERAND;  //デスティネーションオペランド転送開始
        return;

      case 0b100:  //$B000: FMOVE.L FPCR,<ea>
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a b000
        //    > cir 00 ....
        //    8900 B104 0802 0802 
        //    > cir 10 .
        //    00000000 
        //    > cir 00 ..
        //    0802 0802 
        //    --------------------------------
        cirOperandBuffer[0] = epbFpcr;
        cirResponse = 0x8900_b104;  //FPCRを出力する→come_again
        cirOperandLength = 1;
        cirOperandIndex = 0;
        cirStage = CIR_DESTINATION_OPERAND;  //デスティネーションオペランド転送開始
        return;

      case 0b101:  //$B400: FMOVEM.L FPCR/FPIAR,<ea>
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a b400
        //    > cir 00 ....
        //    8900 B208 8900 8900 
        //    > cir 10 .
        //    00000000 
        //    > cir 00 ..
        //    0802 0802 
        //    > cir 10 .
        //    00000000 
        //    > cir 00 ..
        //    0802 0802 
        //    --------------------------------
        cirOperandBuffer[0] = epbFpcr;
        cirOperandBuffer[1] = epbFpiar;
        cirResponse = 0x8900_b208;  //FPCR/FPIARを出力する→come_again
        cirOperandLength = 2;
        cirOperandIndex = 0;
        cirStage = CIR_DESTINATION_OPERAND;  //デスティネーションオペランド転送開始
        return;

      case 0b110:  //$B800: FMOVEM.L FPCR/FPSR,<ea>
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a b800
        //    > cir 00 ....
        //    8900 B208 8900 8900 
        //    > cir 10 .
        //    00000000 
        //    > cir 00 ..
        //    0802 0802 
        //    > cir 10 .
        //    00000000 
        //    > cir 00 ..
        //    0802 0802 
        //    --------------------------------
        cirOperandBuffer[0] = epbFpcr;
        cirOperandBuffer[1] = epbFpsr;
        cirResponse = 0x8900_b208;  //FPCR/FPSRを出力する→come_again
        cirOperandLength = 2;
        cirOperandIndex = 0;
        cirStage = CIR_DESTINATION_OPERAND;  //デスティネーションオペランド転送開始
        return;

      case 0b111:  //$BC00: FMOVEM.L FPCR/FPSR/FPIAR,<ea>
        //    --------------------------------
        //    > cir 00 .
        //    0802 
        //    > cir 0a bc00
        //    > cir 00 ....
        //    8900 B20C 8900 8900 
        //    > cir 10 .
        //    00000000 
        //    > cir 00 ..
        //    8900 8900 
        //    > cir 10 .
        //    00000000 
        //    > cir 00 ..
        //    0802 0802 
        //    > cir 10 .
        //    00000000 
        //    > cir 00 ..
        //    0802 0802 
        //    --------------------------------
      default:
        cirOperandBuffer[0] = epbFpcr;
        cirOperandBuffer[1] = epbFpsr;
        cirOperandBuffer[2] = epbFpiar;
        cirResponse = 0x8900_b20c;  //FPCR/FPSR/FPIARを出力する→come_again
        cirOperandLength = 3;
        cirOperandIndex = 0;
        cirStage = CIR_DESTINATION_OPERAND;  //デスティネーションオペランド転送開始
        return;
      }
      //break;


    case 0b110:  //$Cxxx-$Dxxx: FMOVEM.X <ea>,<list>
      //  FMOVEM命令は例外を発生させずFPCR/FPSR/FPIARも(デスティネーションに書かれたもの以外)変化しない
      //    --------------------------------
      //    > cir 00 .
      //    0802 
      //    > cir 0a d0ff
      //    > cir 00 ....
      //    8900 810C 8900 8900 
      //    > cir 14 .
      //    FF00 
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 3fff0000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 80000000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 00000000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 40000000 80000000 00000000
      //    > cir 10 40010000 80000000 00000000
      //    > cir 10 40020000 80000000 00000000
      //    > cir 10 40030000 80000000 00000000
      //    > cir 10 40040000 80000000 00000000
      //    > cir 10 40050000 80000000 00000000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 40060000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 80000000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 00000000
      //    > cir 00 ..
      //    0802 0802 
      //    --------------------------------
      //    レスポンス$810Cが帰った直後に$14 register selectをリードしないとプロトコル違反になる
      //    > cir 00 .
      //    0802 
      //    > cir 0a d0ff
      //    > cir 00 ....
      //    8900 810C 8900 8900 
      //    > cir 10 3fff0000
      //    > cir 00 ..
      //    1D0D 1D0D 
      //    > cir 06 0000
      //    > cir 00 ..
      //    0802 0802 
      //    --------------------------------
      //    転送するレジスタがなくても$14 register selectを1回だけリードしなければならない
      //    > cir 00 .
      //    0802 
      //    > cir 0a d000
      //    > cir 00 ....
      //    8900 810C 0802 0802 
      //    > cir 0a 0000
      //    > cir 00 ..
      //    1D0D 1D0D 
      //    > cir 06 0000
      //    > cir 00 ..
      //    0802 0802 
      //    > cir 00 .
      //    0802 
      //    > cir 0a d000
      //    > cir 00 ....
      //    8900 810C 0802 0802 
      //    > cir 14 .
      //    0000 
      //    > cir 00 ..
      //    0802 0802 
      //    > cir 14 .
      //    0000 
      //    > cir 00 ..
      //    1D0D 1D0D 
      //    > cir 06 0000
      //    > cir 00 ..
      //    0802 0802 
      //    --------------------------------
      //    fmovem.x -(a0),fp0-fp7が許容される。転送順序はFP7→FP6→...→FP1→FP0
      //    > cir 00 .
      //    0802 
      //    > cir 0a c0ff
      //    > cir 00 ....
      //    8900 810C 8900 8900 
      //    > cir 14 .
      //    FF00 
      //    > cir 10 3fff0000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 80000000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 00000000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 40000000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 80000000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 00000000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 40010000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 80000000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 00000000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 40020000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 80000000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 00000000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 40030000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 80000000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 00000000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 40040000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 80000000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 00000000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 40050000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 80000000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 00000000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 40060000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 80000000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 00000000
      //    > cir 00 ..
      //    0802 0802 
      //    > cir 00 .
      //    0802 
      //    > cir 0a 6000
      //    > cir 00 ....
      //    8900 B104 0802 0802 
      //    > cir 10 .
      //    00000080 
      //    --------------------------------
      //    memory to FPCP, pre-decrment, static register list
      //    > cir 00 .
      //    0802 
      //    > cir 0a c001
      //    > cir 00 ....
      //    8900 810C 8900 8900 
      //    > cir 14 .
      //    0100 
      //    > cir 00 ....
      //    8900 8900 8900 8900 
      //    > cir 10 40020000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 b0000000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 00000000
      //    > cir 00 ..
      //    0802 0802 
      //    > cir 0a 6000
      //    > cir 00 ....
      //    8900 B104 0802 0802 
      //    > cir 10 .
      //    0000000B 
      //    > cir 00 ..
      //    0802 0802 
      //    --------------------------------
      //    memory to FPCP, pre-decrment, dynamic register list
      //    > cir 00 .
      //    0802 
      //    > cir 0a c850
      //    > cir 00 ....
      //    8C05 8900 8900 8900 
      //    > cir 10 00000001
      //    > cir 00 ....
      //    810C 8900 8900 8900 
      //    > cir 14 .
      //    0100 
      //    > cir 10 40020000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 90000000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 00000000
      //    > cir 00 ..
      //    0802 0802 
      //    > cir 0a 6000
      //    > cir 00 ....
      //    8900 B104 0802 0802 
      //    > cir 10 .
      //    00000009 
      //    > cir 00 ..
      //    0802 0802 
      //    --------------------------------
      //    memory to FPCP, post-increment, static register list
      //    > cir 00 .
      //    0802 
      //    > cir 0a d080
      //    > cir 00 ....
      //    8900 810C 8900 8900 
      //    > cir 14 .
      //    8000 
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 40010000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 a0000000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 00000000
      //    > cir 00 ..
      //    0802 0802 
      //    > cir 0a 6000
      //    > cir 00 ....
      //    8900 B104 0802 0802 
      //    > cir 10 .
      //    00000005 
      //    > cir 00 ..
      //    0802 0802 
      //    --------------------------------
      //    memory to FPCP, post-increment, dynamic register list
      //    > cir 00 .
      //    0802 
      //    > cir 0a d870
      //    > cir 00 ....
      //    8C07 8900 8900 8900 
      //    > cir 10 00000080
      //    > cir 00 ...
      //    810C 8900 8900 
      //    > cir 14 .
      //    8000 
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 40000000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 c0000000
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 00000000
      //    > cir 00 ..
      //    0802 0802 
      //    > cir 0a 6000
      //    > cir 00 ....
      //    8900 B104 0802 0802 
      //    > cir 10 .
      //    00000003 
      //    > cir 00 ..
      //    0802 0802 
      //    --------------------------------
      if (cirStage == CIR_IDLE) {  //開始
        if ((cirCommand & 0x0700) != 0) {
          cirException (0x1c0b);  //F-line emulator
          return;
        }
        if ((mmm & 2) == 0) {  //静的レジスタリスト
          cirRegisterList = cirCommand & 255;
          cirResponse = 0x8900_810c;  //複数レジスタを入力する→come_again
          cirStage = CIR_REGISTER_SELECT;  //レジスタセレクト転送開始
        } else {  //動的レジスタリスト
          cirResponse = 0x8900_8c00 + (cirCommand >> 4 & 7);  //データレジスタを入力する→come-again
          cirOperandLength = 1;
          cirOperandIndex = 0;
          cirStage = CIR_DYNAMIC_REGISTER_LIST;  //動的レジスタリスト転送開始
        }
        return;
      }
      if (cirStage == CIR_DYNAMIC_REGISTER_LIST) {  //動的レジスタリスト転送終了
        cirRegisterList = cirOperandBuffer[0] & 255;
        cirResponse = 0x8900_810c;  //複数レジスタを入力する→come_again
        cirStage = CIR_REGISTER_SELECT;  //レジスタセレクト転送開始
        return;
      }
      if (cirStage == CIR_REGISTER_SELECT) {  //レジスタセレクト転送終了
        if (cirRegisterList == 0) {  //転送するレジスタがない
          //終了
          cirIdle (0x0802);
          return;
        }
        cirOperandLength = 3 * Integer.bitCount (cirRegisterList);  //転送するレジスタ数*3=転送するロング数
        cirOperandIndex = 0;
        cirStage = CIR_SOURCE_OPERAND;  //ソースオペランド転送開始
        return;
      }
      //if (cirStage == CIR_SOURCE_OPERAND)
      {  //ソースオペランド転送終了
        int n, p;
        if ((cirCommand & 0x1000) == 0) {  //プレデクリメント。リストはFP7|…|FP0、転送順序はFP7→FP0、オペランドバッファはFP0,…,FP7
          n = 7;
          p = -1;
        } else {  //ポストインクリメント。リストはFP0|…|FP7、転送順序はFP0→FP7、オペランドバッファはFP7,…,FP0
          n = 0;
          p = 1;
        }
        int i = 0;
        for (int list = cirRegisterList << 24; list != 0; n += p, list <<= 1) {
          if (list < 0) {
            if (epbIsTriple ()) {  //三倍精度
              epbFPn[n].sety012 (cirOperandBuffer[i], (long) cirOperandBuffer[i + 1] << 32 | cirOperandBuffer[i + 2] & 0xffffffffL);
            } else {  //拡張精度
              epbFPn[n].setx012 (cirOperandBuffer[i], (long) cirOperandBuffer[i + 1] << 32 | cirOperandBuffer[i + 2] & 0xffffffffL);
            }
            i += 3;
          }
        }
        //終了
        cirIdle (0x0802);
        return;
      }
      //break;


    case 0b111:  //$Exxx-$Fxxx: FMOVEM.X <list>,<ea>
      //  FMOVEM命令は例外を発生させずFPCR/FPSR/FPIARも(デスティネーションに書かれたもの以外)変化しない
      //    --------------------------------
      //    FPCP to memory, pre-decrement, static register list
      //    > cir 00 .
      //    0802 
      //    > cir 0a 4000
      //    > cir 00 ....
      //    9504 8900 8900 8900 
      //    > cir 10 00000080
      //    > cir 00 ..
      //    0802 0802 
      //    > cir 0a 4080
      //    > cir 00 ....
      //    9504 8900 8900 8900 
      //    > cir 10 00000081
      //    > cir 00 ..
      //    0802 0802 
      //    > cir 0a e003
      //    > cir 00 ....
      //    8900 A10C 8900 8900 
      //    > cir 14 .
      //    0300 
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 .
      //    40060000 
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 .
      //    81000000 
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 .
      //    00000000 
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 .
      //    40060000 
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 .
      //    80000000 
      //    > cir 00 ..
      //    0802 0802 
      //    --------------------------------
      //    FPCP to memory, pre-decrement, dynamic register list
      //    > cir 00 .
      //    0802 
      //    > cir 0a 4000
      //    > cir 00 ....
      //    9504 8900 8900 8900 
      //    > cir 10 00000082
      //    > cir 00 ..
      //    0802 0802 
      //    > cir 0a 4080
      //    > cir 00 ....
      //    9504 8900 8900 8900 
      //    > cir 10 00000083
      //    > cir 00 ..
      //    0802 0802 
      //    > cir 0a e870
      //    > cir 00 ....
      //    8C07 8900 8900 8900 
      //    > cir 10 00000003
      //    > cir 00 ....
      //    A10C 8900 8900 8900 
      //    > cir 14 .
      //    0300 
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 ...
      //    40060000 83000000 00000000 
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 ...
      //    40060000 82000000 00000000 
      //    > cir 00 ..
      //    0802 0802 
      //    --------------------------------
      //    FPCP to memory, post-increment, static register list
      //    > cir 00 .
      //    0802 
      //    > cir 0a 4000
      //    > cir 00 ....
      //    9504 8900 8900 8900 
      //    > cir 10 00000084
      //    > cir 00 ..
      //    0802 0802 
      //    > cir 0a 4080
      //    > cir 00 ....
      //    9504 8900 8900 8900 
      //    > cir 10 00000085
      //    > cir 00 ..
      //    0802 0802 
      //    > cir 0a f0c0
      //    > cir 00 ....
      //    8900 A10C 8900 8900 
      //    > cir 14 .
      //    C000 
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 ...
      //    40060000 84000000 00000000 
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 ...
      //    40060000 85000000 00000000 
      //    > cir 00 ..
      //    0802 0802 
      //    --------------------------------
      //    FPCP to memory, post-increment, dynamic register list
      //    > cir 00 .
      //    0802 
      //    > cir 0a 4000
      //    > cir 00 ....
      //    9504 8900 8900 8900 
      //    > cir 10 00000086
      //    > cir 00 ..
      //    0802 0802 
      //    > cir 0a 4080
      //    > cir 00 ....
      //    9504 8900 8900 8900 
      //    > cir 10 00000087
      //    > cir 00 ..
      //    0802 0802 
      //    > cir 0a f870
      //    > cir 00 ....
      //    8C07 8900 8900 8900 
      //    > cir 10 000000c0
      //    > cir 00 ....
      //    A10C 8900 8900 8900 
      //    > cir 14 .
      //    C000 
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 ...
      //    40060000 86000000 00000000 
      //    > cir 00 ..
      //    8900 8900 
      //    > cir 10 ...
      //    40060000 87000000 00000000 
      //    > cir 00 ..
      //    0802 0802 
      //    --------------------------------
      if (cirStage == CIR_IDLE) {  //開始
        if ((cirCommand & 0x0700) != 0) {
          cirException (0x1c0b);  //F-line emulator
          return;
        }
        if ((mmm & 2) == 0) {  //静的レジスタリスト
          cirRegisterList = cirCommand & 255;
          cirResponse = 0x8900_a10c;  //複数レジスタを出力する→come_again
          cirStage = CIR_REGISTER_SELECT;  //レジスタセレクト転送開始
        } else {  //動的レジスタリスト
          cirResponse = 0x8900_8c00 + (cirCommand >> 4 & 7);  //データレジスタを入力する→come-again
          cirOperandLength = 1;
          cirOperandIndex = 0;
          cirStage = CIR_DYNAMIC_REGISTER_LIST;  //動的レジスタリスト転送開始
        }
        return;
      }
      if (cirStage == CIR_DYNAMIC_REGISTER_LIST) {  //動的レジスタリスト転送終了
        cirRegisterList = cirOperandBuffer[0] & 255;
        cirResponse = 0x8900_a10c;  //複数レジスタを出力する→come_again
        cirStage = CIR_REGISTER_SELECT;  //レジスタセレクト転送開始
        return;
      }
      if (cirStage == CIR_REGISTER_SELECT) {  //レジスタセレクト転送終了
        if (cirRegisterList == 0) {  //転送するレジスタがない
          //終了
          cirIdle (0x0802);
          return;
        }
        int n, p;
        if ((cirCommand & 0x1000) == 0) {  //プレデクリメント。リストはFP7|…|FP0、転送順序はFP7→FP0、オペランドバッファはFP0,…,FP7
          n = 7;
          p = -1;
        } else {  //ポストインクリメント。リストはFP0|…|FP7、転送順序はFP0→FP7、オペランドバッファはFP7,…,FP0
          n = 0;
          p = 1;
        }
        int i = 0;
        byte[] b = new byte[12];
        for (int list = cirRegisterList << 24; list != 0; n += p, list <<= 1) {
          if (list < 0) {
            if (epbIsTriple ()) {  //三倍精度
              epbFPn[n].gety012 (b, 0, epbRoundingMode);
            } else {  //拡張精度
              epbFPn[n].getx012 (b, 0, epbRoundingMode);
            }
            cirOperandBuffer[i] = b[0] << 24 | (b[1] & 255) << 16 | (char) (b[2] << 8 | b[3] & 255);
            cirOperandBuffer[i + 1] = b[4] << 24 | (b[5] & 255) << 16 | (char) (b[6] << 8 | b[7] & 255);
            cirOperandBuffer[i + 2] = b[8] << 24 | (b[9] & 255) << 16 | (char) (b[10] << 8 | b[11] & 255);
            i += 3;
          }
        }
        cirOperandLength = i;
        cirOperandIndex = 0;
        cirStage = CIR_DESTINATION_OPERAND;  //デスティネーションオペランド転送開始
        return;
      }
      //if (cirStage == CIR_DESTINATION_OPERAND)
      {  //デスティネーションオペランド転送終了
        //終了
        cirIdle (0x0802);
        return;
      }
      //break;


    case 0b001:  //$2xxx-$3xxx: 未定義
    default:
      cirException (0x1c0b);  //F-line emulator
      return;
    }

  }  //cirGen()


  //cirPreInstruction ()
  //  浮動小数点命令実行前例外
  //  優先順位はBSUN>SNAN>OPERR>OVFL>UNFL>DZ>INEX2/INEX1
  //  複数の例外が同時に発生したときは最上位の例外ハンドラだけが呼び出される
  //  浮動小数点例外ハンドラは自分よりも下位の浮動小数点例外が発生していないか確認しなければならない
  public boolean cirPreInstruction () {
    //FPSRのAEXCを更新する
    epbFpsr |= XEiJ.FPU_FPSR_EXC_TO_AEXC[epbFpsr >> 8 & 255];
    //浮動小数点命令実行前例外 floating-point pre-instruction exception
    int mask = epbFpcr & epbFpsr & 0x0000ff00;
    if (mask == 0) {
      return false;
    }
    if ((short) mask < 0) {  //BSUN。(mask & 0x00008000) != 0
      cirException (0x5c30);  //分岐または比較不能状態でのセット branch or set on unordered
    } else if (mask << 17 < 0) {  //SNAN。(mask & 0x00004000) != 0
      cirException (0x1c36);  //シグナリングNAN signaling nan
    } else if (mask << 18 < 0) {  //OPERR。(mask & 0x00002000) != 0
      cirException (0x1c34);  //オペランドエラー operand error
    } else if (mask << 19 < 0) {  //OVFL。(mask & 0x00001000) != 0
      cirException (0x1c35);  //オーバーフロー overflow
    } else if (mask << 20 < 0) {  //UNFL。(mask & 0x00000800) != 0
      cirException (0x1c33);  //アンダーフロー underflow
    } else if (mask << 21 < 0) {  //DZ。(mask & 0x00000400) != 0
      cirException (0x1c32);  //ゼロによる除算 floating-point divide by zero
    } else {  //INEX1,INEX2。(mask & 0x00000300) != 0
      cirException (0x1c31);  //不正確な結果 inexact result
    }
    return true;
  }  //cirPreInstruction()

  //cirMidInstruction ()
  //  浮動小数点命令実行中例外
  //  優先順位はBSUN>SNAN>OPERR>OVFL>UNFL>DZ>INEX2/INEX1
  //  複数の例外が同時に発生したときは最上位の例外ハンドラだけが呼び出される
  //  浮動小数点例外ハンドラは自分よりも下位の浮動小数点例外が発生していないか確認しなければならない
  public boolean cirMidInstruction () {
    //FPSRのAEXCを更新する
    epbFpsr |= XEiJ.FPU_FPSR_EXC_TO_AEXC[epbFpsr >> 8 & 255];
    //浮動小数点命令実行中例外 floating-point mid-instruction exception
    int mask = epbFpcr & epbFpsr & 0x0000ff00;
    if (mask == 0) {
      return false;
    }
    if ((short) mask < 0) {  //BSUN。(mask & 0x00008000) != 0
      cirException (0x5d30);  //分岐または比較不能状態でのセット branch or set on unordered
    } else if (mask << 17 < 0) {  //SNAN。(mask & 0x00004000) != 0
      cirException (0x1d36);  //シグナリングNAN signaling nan
    } else if (mask << 18 < 0) {  //OPERR。(mask & 0x00002000) != 0
      cirException (0x1d34);  //オペランドエラー operand error
    } else if (mask << 19 < 0) {  //OVFL。(mask & 0x00001000) != 0
      cirException (0x1d35);  //オーバーフロー overflow
    } else if (mask << 20 < 0) {  //UNFL。(mask & 0x00000800) != 0
      cirException (0x1d33);  //アンダーフロー underflow
    } else if (mask << 21 < 0) {  //DZ。(mask & 0x00000400) != 0
      cirException (0x1d32);  //ゼロによる除算 floating-point divide by zero
    } else {  //INEX1,INEX2。(mask & 0x00000300) != 0
      cirException (0x1d31);  //不正確な結果 inexact result
    }
    return true;
  }  //cirMidInstruction()



}  //class EPB


1 2 3