FEFunction.java
     1: //========================================================================================
     2: //  FEFunction.java
     3: //    en:FE function
     4: //    ja:FEファンクション
     5: //  Copyright (C) 2003-2023 Makoto Kamada
     6: //
     7: //  This file is part of the XEiJ (X68000 Emulator in Java).
     8: //  You can use, modify and redistribute the XEiJ if the conditions are met.
     9: //  Read the XEiJ License for more details.
    10: //  https://stdkmd.net/xeij/
    11: //========================================================================================
    12: 
    13: //----------------------------------------------------------------------------------------
    14: //  FEファンクションコール(オペコード0xfe00~0xfeff)をMPUの命令として処理することで高速化する
    15: //  line 1111 emulator/privilege violation例外が発生しないのでFLOATn.Xが組み込まれていてもFLOATn.Xのルーチンは使用されない
    16: //----------------------------------------------------------------------------------------
    17: 
    18: package xeij;
    19: 
    20: import java.lang.*;  //Boolean,Character,Class,Comparable,Double,Exception,Float,IllegalArgumentException,Integer,Long,Math,Number,Object,Runnable,SecurityException,String,StringBuilder,System
    21: 
    22: public class FEFunction {
    23: 
    24:   public static final boolean FPK_DEBUG_TRACE = false;
    25: 
    26:   public static final int FPK_CLOCK = 80;  //一律に80サイクルかかることにする
    27: 
    28:   public static final boolean FPK_FPCP_NAN = true;  //true=JavaのNaN(0x7ff8000000000000L,0x7fc00000)をFPCPのNaN(0x7fffffffffffffffL,0x7fffffff)に変換する
    29: 
    30:   public static boolean fpkOn;  //true=FEファンクションコールを命令として処理する
    31: 
    32:   //  Human68kのline 1111 emulator/privilege violation例外処理ルーチンの手前にFLOATn.Xのマジック'FEfn'を押し込む
    33:   //  CONFIG.SYSにFLOATn.Xが書いてあっても「すでに浮動小数点演算パッケージは登録されています」と表示されて組み込まれなくなる
    34:   //  FLOATn.Xを組み込んでもFEファンクションが命令として処理されることに変わりはないが、
    35:   //  FLOATn.Xを組み込まなければFライン例外がFLOATn.Xを通らなくなるのでDOSコールのオーバーヘッドが少なくなる
    36:   public static boolean fpkRejectFloatOn;  //true=FLOATn.Xを組み込まない
    37: 
    38:   public static void fpkInit () {
    39:     fpkOn = Settings.sgsGetOnOff ("fefunc");  //FEファンクション命令
    40:     fpkRejectFloatOn = Settings.sgsGetOnOff ("rejectfloat");  //FLOATn.Xを組み込まない
    41:   }  //fpkInit()
    42: 
    43: 
    44: 
    45:   public static final int[] fpkRndTable = new int[55];
    46:   public static int fpkRndPointer = -1;
    47: 
    48:   //fpkRndInit ()
    49:   //  rnd()乱数列の初期化
    50:   public static void fpkRndInit (int t) {
    51:     for (int i = 0; i < 55; i++) {
    52:       t = (char) t * 15625 + 1;  //15625=5^6
    53:       fpkRndTable[i] = t << 16 | (char) t;
    54:     }
    55:     fpkRndPointer = 54;
    56:     fpkRndShuffle ();
    57:     fpkRndShuffle ();
    58:     fpkRndShuffle ();
    59:   }  //fpkRndInit()
    60: 
    61:   //fpkRndShuffle ()
    62:   //  rnd()乱数列の更新
    63:   public static void fpkRndShuffle () {
    64:     for (int i = 0; i < 24; i++) {
    65:       fpkRndTable[i] -= fpkRndTable[i + 31];
    66:     }
    67:     for (int i = 24; i < 55; i++) {
    68:       fpkRndTable[i] -= fpkRndTable[i - 24];
    69:     }
    70:   }  //fpkRndShuffle()
    71: 
    72:   //rnd = fpkRndLong ()
    73:   //  rnd()乱数列の取り出し
    74:   public static int fpkRndLong () {
    75:     int i = fpkRndPointer;
    76:     if (i < 0) {
    77:       fpkRndInit (111);
    78:       i = fpkRndPointer;
    79:     }
    80:     if (i == 54) {
    81:       fpkRndShuffle ();
    82:       i = 0;
    83:     } else {
    84:       i++;
    85:     }
    86:     fpkRndPointer = i;
    87:     return fpkRndTable[i];
    88:   }  //fpkRndLong()
    89: 
    90: 
    91: 
    92:   public static final short[] fpkRandTable = new short[55];
    93:   public static int fpkRandPointer = -1;
    94: 
    95:   //fpkRandInit (t)
    96:   //  rand()乱数列の初期化
    97:   public static void fpkRandInit (int t) {
    98:     for (int i = 0; i < 55; i++) {
    99:       t = (char) t * 15625 + 1;
   100:       fpkRandTable[i] = (short) t;
   101:     }
   102:     fpkRandPointer = 54;
   103:     fpkRandShuffle ();
   104:   }  //fpkRandInit(int)
   105: 
   106:   //fpkRandShuffle ()
   107:   //  rand()乱数列の更新
   108:   public static void fpkRandShuffle () {
   109:     for (int i = 0; i < 24; i++) {
   110:       fpkRandTable[i] -= fpkRandTable[i + 31];
   111:     }
   112:     for (int i = 24; i < 55; i++) {
   113:       fpkRandTable[i] -= fpkRandTable[i - 24];
   114:     }
   115:   }  //fpkRandShuffle()
   116: 
   117:   //rand = fpkRandShort ()
   118:   //  rand()乱数列の取り出し
   119:   public static short fpkRandShort () {
   120:     int i = fpkRandPointer;
   121:     if (i < 0) {
   122:       fpkRandInit (51);
   123:       i = fpkRandPointer;
   124:     }
   125:     if (i == 54) {
   126:       fpkRandShuffle ();
   127:       i = 0;
   128:     } else {
   129:       i++;
   130:     }
   131:     fpkRandPointer = i;
   132:     return fpkRandTable[i];
   133:   }  //fpkRandShort()
   134: 
   135:   //10^(±16^q*r)のテーブル
   136:   //  10進数の指数部を4bitずつ分割して10^(±16^q*r)のテーブルを参照する
   137:   //  4bitずつ分割するのは誤差を減らすため
   138:   //  3bitずつ分割しても3分割に変わりないが非正規化数の最小値4.94e-324を処理するときに1.0e+320が必要になるので不可
   139:   //  一般的には10進数の指数部を1bitずつ分割して10^(±2^q)のテーブルを参照することが多い
   140:   //  誤差を小さくしたければ分割せずに直接10^(±r)のテーブルを参照する方法もある。doubleならば高々600個余りである
   141:   public static final double[] FPK_TEN_P16QR = {
   142:     //  perl -e "for$i(0..33){$q=$i>>4;$r=$i&15;printf'    1.0e+%d,  //10^(16^%d*%d)%c',16**$q*$r,$q,$r,10}"
   143:     1.0e+0,  //10^(16^0*0)
   144:     1.0e+1,  //10^(16^0*1)
   145:     1.0e+2,  //10^(16^0*2)
   146:     1.0e+3,  //10^(16^0*3)
   147:     1.0e+4,  //10^(16^0*4)
   148:     1.0e+5,  //10^(16^0*5)
   149:     1.0e+6,  //10^(16^0*6)
   150:     1.0e+7,  //10^(16^0*7)
   151:     1.0e+8,  //10^(16^0*8)
   152:     1.0e+9,  //10^(16^0*9)
   153:     1.0e+10,  //10^(16^0*10)
   154:     1.0e+11,  //10^(16^0*11)
   155:     1.0e+12,  //10^(16^0*12)
   156:     1.0e+13,  //10^(16^0*13)
   157:     1.0e+14,  //10^(16^0*14)
   158:     1.0e+15,  //10^(16^0*15)
   159:     1.0e+0,  //10^(16^1*0)
   160:     1.0e+16,  //10^(16^1*1)
   161:     1.0e+32,  //10^(16^1*2)
   162:     1.0e+48,  //10^(16^1*3)
   163:     1.0e+64,  //10^(16^1*4)
   164:     1.0e+80,  //10^(16^1*5)
   165:     1.0e+96,  //10^(16^1*6)
   166:     1.0e+112,  //10^(16^1*7)
   167:     1.0e+128,  //10^(16^1*8)
   168:     1.0e+144,  //10^(16^1*9)
   169:     1.0e+160,  //10^(16^1*10)
   170:     1.0e+176,  //10^(16^1*11)
   171:     1.0e+192,  //10^(16^1*12)
   172:     1.0e+208,  //10^(16^1*13)
   173:     1.0e+224,  //10^(16^1*14)
   174:     1.0e+240,  //10^(16^1*15)
   175:     1.0e+0,  //10^(16^2*0)
   176:     1.0e+256,  //10^(16^2*1)
   177:   };
   178:   public static final double[] FPK_TEN_M16QR = {
   179:     //  perl -e "for$i(0..33){$q=$i>>4;$r=$i&15;printf'    1.0e-%d,  //10^(-16^%d*%d)%c',16**$q*$r,$q,$r,10}"
   180:     1.0e-0,  //10^(-16^0*0)
   181:     1.0e-1,  //10^(-16^0*1)
   182:     1.0e-2,  //10^(-16^0*2)
   183:     1.0e-3,  //10^(-16^0*3)
   184:     1.0e-4,  //10^(-16^0*4)
   185:     1.0e-5,  //10^(-16^0*5)
   186:     1.0e-6,  //10^(-16^0*6)
   187:     1.0e-7,  //10^(-16^0*7)
   188:     1.0e-8,  //10^(-16^0*8)
   189:     1.0e-9,  //10^(-16^0*9)
   190:     1.0e-10,  //10^(-16^0*10)
   191:     1.0e-11,  //10^(-16^0*11)
   192:     1.0e-12,  //10^(-16^0*12)
   193:     1.0e-13,  //10^(-16^0*13)
   194:     1.0e-14,  //10^(-16^0*14)
   195:     1.0e-15,  //10^(-16^0*15)
   196:     1.0e-0,  //10^(-16^1*0)
   197:     1.0e-16,  //10^(-16^1*1)
   198:     1.0e-32,  //10^(-16^1*2)
   199:     1.0e-48,  //10^(-16^1*3)
   200:     1.0e-64,  //10^(-16^1*4)
   201:     1.0e-80,  //10^(-16^1*5)
   202:     1.0e-96,  //10^(-16^1*6)
   203:     1.0e-112,  //10^(-16^1*7)
   204:     1.0e-128,  //10^(-16^1*8)
   205:     1.0e-144,  //10^(-16^1*9)
   206:     1.0e-160,  //10^(-16^1*10)
   207:     1.0e-176,  //10^(-16^1*11)
   208:     1.0e-192,  //10^(-16^1*12)
   209:     1.0e-208,  //10^(-16^1*13)
   210:     1.0e-224,  //10^(-16^1*14)
   211:     1.0e-240,  //10^(-16^1*15)
   212:     1.0e-0,  //10^(-16^2*0)
   213:     1.0e-256,  //10^(-16^2*1)
   214:   };
   215: 
   216: 
   217: 
   218:   //fpkLMUL ()
   219:   //  $FE00  __LMUL
   220:   //  32bit符号あり整数乗算
   221:   //  <d0.l:32bit符号あり整数。被乗数x
   222:   //  <d1.l:32bit符号あり整数。乗数y
   223:   //  >d0.l:32bit符号あり整数。積x*y。オーバーフローのときは不定
   224:   //  >ccr:cs=オーバーフロー。C以外は不定
   225:   public static void fpkLMUL () {
   226:     long l = (long) XEiJ.regRn[0] * (long) XEiJ.regRn[1];
   227:     int h = (int) l;
   228:     XEiJ.regRn[0] = h;  //オーバーフローのときは積の下位32bit
   229:     XEiJ.regCCR = (long) h == l ? 0 : XEiJ.REG_CCR_C;
   230:   }  //fpkLMUL()
   231: 
   232:   //fpkLDIV ()
   233:   //  $FE01  __LDIV
   234:   //  32bit符号あり整数除算
   235:   //  バグ
   236:   //    FLOAT2.X 2.02/2.03は0x00000000/0x00000000がエラーにならない
   237:   //    FLOAT2.X 2.02/2.03は0x80000000/0xffffffff=0x80000000がエラーになる
   238:   //  <d0.l:32bit符号あり整数。被除数x
   239:   //  <d1.l:32bit符号あり整数。除数y
   240:   //  >d0.l:32bit符号あり整数。商x/y。ゼロ除算のときは不定
   241:   //  >ccr:cs=ゼロ除算。C以外は不定
   242:   public static void fpkLDIV () {
   243:     int h = XEiJ.regRn[1];
   244:     if (h == 0) {  //ゼロ除算
   245:       //r[0]は変化しない
   246:       XEiJ.regCCR = XEiJ.REG_CCR_C;
   247:     } else {
   248:       XEiJ.regRn[0] /= h;
   249:       XEiJ.regCCR = 0;
   250:     }
   251:   }  //fpkLDIV()
   252: 
   253:   //fpkLMOD ()
   254:   //  $FE02  __LMOD
   255:   //  32bit符号あり整数剰余算
   256:   //  バグ
   257:   //    FLOAT2.X 2.02/2.03は0x00000000%0x00000000がエラーにならない
   258:   //    FLOAT4.X 1.02は0x80000000%0xffffffff=0x00000000が0xffffffffになる(実機で確認済み)
   259:   //  <d0.l:32bit符号あり整数。被除数x
   260:   //  <d1.l:32bit符号あり整数。除数y
   261:   //  >d0.l:32bit符号あり整数。余りx%y。ゼロ除算のときは不定
   262:   //  >ccr:cs=ゼロ除算。C以外は不定
   263:   public static void fpkLMOD () {
   264:     int h = XEiJ.regRn[1];
   265:     if (h == 0) {  //ゼロ除算
   266:       //r[0]は変化しない
   267:       XEiJ.regCCR = XEiJ.REG_CCR_C;
   268:     } else {
   269:       XEiJ.regRn[0] %= h;
   270:       XEiJ.regCCR = 0;
   271:     }
   272:   }  //fpkLMOD()
   273: 
   274:   //fpkUMUL ()
   275:   //  $FE04  __UMUL
   276:   //  32bit符号なし整数乗算
   277:   //  <d0.l:32bit符号なし整数。被乗数x
   278:   //  <d1.l:32bit符号なし整数。乗数y
   279:   //  >d0.l:32bit符号なし整数。積x*y。オーバーフローのときは不定
   280:   //  >ccr:cs=オーバーフロー。C以外は不定
   281:   public static void fpkUMUL () {
   282:     long l = (0xffffffffL & XEiJ.regRn[0]) * (0xffffffffL & XEiJ.regRn[1]);
   283:     int h = (int) l;
   284:     XEiJ.regRn[0] = h;  //オーバーフローのときは積の下位32bit
   285:     XEiJ.regCCR = (0xffffffffL & h) == l ? 0 : XEiJ.REG_CCR_C;
   286:   }  //fpkUMUL()
   287: 
   288:   //fpkUDIV ()
   289:   //  $FE05  __UDIV
   290:   //  32bit符号なし整数除算
   291:   //  バグ
   292:   //    FLOAT2.X 2.02/2.03は0x00000000/0x00000000がエラーにならない
   293:   //  <d0.l:32bit符号なし整数。被除数x
   294:   //  <d1.l:32bit符号なし整数。除数y
   295:   //  >d0.l:32bit符号なし整数。商x/y。ゼロ除算のときは不定
   296:   //  >ccr:cs=ゼロ除算。C以外は不定
   297:   public static void fpkUDIV () {
   298:     int h = XEiJ.regRn[1];
   299:     if (h == 0) {  //ゼロ除算
   300:       //r[0]は変化しない
   301:       XEiJ.regCCR = XEiJ.REG_CCR_C;
   302:     } else {
   303:       XEiJ.regRn[0] = (int) ((0xffffffffL & XEiJ.regRn[0]) / (0xffffffffL & h));
   304:       XEiJ.regCCR = 0;
   305:     }
   306:   }  //fpkUDIV()
   307: 
   308:   //fpkUMOD ()
   309:   //  $FE06  __UMOD
   310:   //  32bit符号なし整数剰余算
   311:   //  バグ
   312:   //    FLOAT2.X 2.02/2.03は0x00000000%0x00000000がエラーにならない
   313:   //  <d0.l:32bit符号なし整数。被除数x
   314:   //  <d1.l:32bit符号なし整数。除数y
   315:   //  >d0.l:32bit符号なし整数。余りx%y。ゼロ除算のときは不定
   316:   //  >ccr:cs=ゼロ除算。C以外は不定
   317:   public static void fpkUMOD () {
   318:     int h = XEiJ.regRn[1];
   319:     if (h == 0) {  //ゼロ除算
   320:       //r[0]は変化しない
   321:       XEiJ.regCCR = XEiJ.REG_CCR_C;
   322:     } else {
   323:       XEiJ.regRn[0] = (int) ((0xffffffffL & XEiJ.regRn[0]) % (0xffffffffL & h));
   324:       XEiJ.regCCR = 0;
   325:     }
   326:   }  //fpkUMOD()
   327: 
   328:   //fpkIMUL ()
   329:   //  $FE08  __IMUL
   330:   //  32bit符号なし整数乗算
   331:   //  <d0.l:32bit符号なし整数。被乗数x
   332:   //  <d1.l:32bit符号なし整数。乗数y
   333:   //  >d0d1.q:64bit符号なし整数。積x*y
   334:   public static void fpkIMUL () {
   335:     long l = (0xffffffffL & XEiJ.regRn[0]) * (0xffffffffL & XEiJ.regRn[1]);
   336:     XEiJ.regRn[0] = (int) (l >>> 32);
   337:     XEiJ.regRn[1] = (int) l;
   338:   }  //fpkIMUL()
   339: 
   340:   //fpkIDIV ()
   341:   //  $FE09  __IDIV
   342:   //  32bit符号なし整数除算・剰余算
   343:   //  <d0.l:32bit符号なし整数。被除数x
   344:   //  <d1.l:32bit符号なし整数。除数y
   345:   //  >d0.l:32bit符号なし整数。商x/y。ゼロ除算のときは不定
   346:   //  >d1.l:32bit符号なし整数。余りx%y。ゼロ除算のときは不定
   347:   //  >ccr:cs=ゼロ除算。C以外は不定
   348:   public static void fpkIDIV () {
   349:     int h = XEiJ.regRn[1];
   350:     if (h == 0) {  //ゼロ除算
   351:       //r[0],r[1]は変化しない
   352:       XEiJ.regCCR = XEiJ.REG_CCR_C;
   353:     } else {
   354:       long xl = 0xffffffffL & XEiJ.regRn[0];
   355:       long yl = 0xffffffffL & h;
   356:       long zl = xl / yl;
   357:       XEiJ.regRn[0] = (int) zl;
   358:       XEiJ.regRn[1] = (int) (xl - zl * yl);
   359:       XEiJ.regCCR = 0;
   360:     }
   361:   }  //fpkIDIV()
   362: 
   363:   //fpkRANDOMIZE ()
   364:   //  $FE0C  __RANDOMIZE
   365:   //  rnd()乱数列の初期化
   366:   //  <d0.l:乱数の種x(0~65535)
   367:   //  >d0.l:0
   368:   public static void fpkRANDOMIZE () {
   369:     fpkRndInit (XEiJ.regRn[0]);
   370:     XEiJ.regRn[0] = 0;
   371:   }  //fpkRANDOMIZE()
   372: 
   373:   //fpkSRAND ()
   374:   //  $FE0D  __SRAND
   375:   //  rand()乱数列の初期化
   376:   //  <d0.l:乱数の種x(0~65535)
   377:   //  >d0.l:0
   378:   public static void fpkSRAND () {
   379:     fpkRandInit (XEiJ.regRn[0]);
   380:     XEiJ.regRn[0] = 0;
   381:   }  //fpkSRAND()
   382: 
   383:   //fpkRAND ()
   384:   //  $FE0E  __RAND
   385:   //  整数乱数
   386:   //  >d0.l:乱数rand()(0~32767)
   387:   public static void fpkRAND () {
   388:     XEiJ.regRn[0] = fpkRandShort () & 0x7fff;
   389:   }  //fpkRAND()
   390: 
   391:   //fpkLTOD ()
   392:   //  $FE1A  __LTOD
   393:   //  32bit符号あり整数を64bit浮動小数点数に変換する
   394:   //  <d0.l:32bit符号あり整数。x
   395:   //  >d0d1.d:64bit浮動小数点数。(double)x
   396:   public static void fpkLTOD () {
   397:     //int→double→[long]→[int,int]
   398:     long l = Double.doubleToLongBits ((double) XEiJ.regRn[0]);
   399:     XEiJ.regRn[0] = (int) (l >>> 32);
   400:     XEiJ.regRn[1] = (int) l;
   401:   }  //fpkLTOD()
   402: 
   403:   //fpkDTOL ()
   404:   //  $FE1B  __DTOL
   405:   //  64bit浮動小数点数を32bit符号あり整数に変換する
   406:   //  <d0d1.d:64bit浮動小数点数。x
   407:   //  >d0.l:32bit符号あり整数。(int)x。オーバーフローのときは不定
   408:   //  >ccr:cs=オーバーフロー。C以外は不定
   409:   public static void fpkDTOL () {
   410:     //[int,int]→[long]→double→int
   411:     double d = Double.longBitsToDouble ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1]);
   412:     XEiJ.regRn[0] = (int) d;  //オーバーフローのときは最小値または最大値
   413:     XEiJ.regCCR = (double) Integer.MIN_VALUE - 1.0 < d && d < (double) Integer.MAX_VALUE + 1.0 ? 0 : XEiJ.REG_CCR_C;  //NaN,±Infはエラー
   414:   }  //fpkDTOL()
   415: 
   416:   //fpkLTOF ()
   417:   //  $FE1C  __LTOF
   418:   //  32bit符号あり整数を32bit浮動小数点数に変換する
   419:   //  <d0.l:32bit符号あり整数。x
   420:   //  >d0.s:32bit浮動小数点数。(float)x
   421:   public static void fpkLTOF () {
   422:     //int→float→[int]
   423:     XEiJ.regRn[0] = Float.floatToIntBits ((float) XEiJ.regRn[0]);
   424:   }  //fpkLTOF()
   425: 
   426:   //fpkFTOL ()
   427:   //  $FE1D  __FTOL
   428:   //  32bit浮動小数点数を32bit符号あり整数に変換する
   429:   //  <d0.s:32bit浮動小数点数。x
   430:   //  >d0.l:32bit符号あり整数。(int)x。オーバーフローのときは不定
   431:   //  >ccr:cs=オーバーフロー。C以外は不定
   432:   public static void fpkFTOL () {
   433:     //[int]→float→int
   434:     float f = Float.intBitsToFloat (XEiJ.regRn[0]);
   435:     XEiJ.regRn[0] = (int) f;
   436:     XEiJ.regCCR = (float) Integer.MIN_VALUE - 1.0F < f && f < (float) Integer.MAX_VALUE + 1.0F ? 0 : XEiJ.REG_CCR_C;  //NaN,±Infはエラー
   437:   }  //fpkFTOL()
   438: 
   439:   //fpkFTOD ()
   440:   //  $FE1E  __FTOD
   441:   //  32bit浮動小数点数を64bit浮動小数点数に変換する
   442:   //  バグ
   443:   //    FLOAT2.X 2.02/2.03はfloatの非正規化数を正しく処理できない
   444:   //      (double)0x007fffff=0x380fffffc0000000Lが0x380fffffe0000000Lになる
   445:   //      (double)0x00000001=0x36a0000000000000Lが0x3800000020000000Lになる
   446:   //  <d0.s:32bit浮動小数点数。x
   447:   //  >d0d1.d:64bit浮動小数点数。(double)x
   448:   public static void fpkFTOD () {
   449:     //[int]→float→double→[long]→[int,int]
   450:     long l = Double.doubleToLongBits ((double) Float.intBitsToFloat (XEiJ.regRn[0]));
   451:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
   452:       l = 0x7fffffffffffffffL;
   453:     }
   454:     XEiJ.regRn[0] = (int) (l >>> 32);
   455:     XEiJ.regRn[1] = (int) l;
   456:   }  //fpkFTOD()
   457: 
   458:   //fpkDTOF ()
   459:   //  $FE1F  __DTOF
   460:   //  64bit浮動小数点数を32bit浮動小数点数に変換する
   461:   //  バグ
   462:   //    FLOAT2.X 2.02/2.03はfloatの非正規化数を正しく処理できない
   463:   //      (float)0x380fffffc0000000L=0x007fffffが0x007ffffeになる
   464:   //      (float)0x36a0000000000000L=0x00000001が0x00000000になる
   465:   //    FLOAT2.X 2.02/2.03は(float)0x8010000000000000L=0x80000000が0x00000000になる
   466:   //  <d0d1.d:64bit浮動小数点数。x
   467:   //  >d0.s:32bit浮動小数点数。(float)x
   468:   //  >ccr:cs=オーバーフロー。C以外は不定
   469:   public static void fpkDTOF () {
   470:     //[int,int]→[long]→double→float→[int]
   471:     double d = Double.longBitsToDouble ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1]);
   472:     int h = Float.floatToIntBits ((float) d);
   473:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
   474:       h = 0x7fffffff;
   475:     }
   476:     XEiJ.regRn[0] = h;
   477:     XEiJ.regCCR = (Double.isNaN (d) || Double.isInfinite (d) ||
   478:            Math.abs (d) < (double) Float.MAX_VALUE + 0.5 * (double) Math.ulp (Float.MAX_VALUE) ? 0 : XEiJ.REG_CCR_C);  //アンダーフローはエラーなし
   479:   }  //fpkDTOF()
   480: 
   481:   //fpkDTST ()
   482:   //  $FE28  __DTST
   483:   //  64bit浮動小数点数と0の比較
   484:   //  x<=>0
   485:   //  バグ
   486:   //    FLOAT2.X 2.02/2.03は-0<0となる
   487:   //    FLOAT4.X 1.02は-0<0となる(実機で確認済み)
   488:   //  <d0d1.d:64bit浮動小数点数。x
   489:   //  >ccr:lt=x<0,eq=x==0,gt=x>0
   490:   public static void fpkDTST () {
   491:     if (true) {
   492:       long l = (long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1];
   493:       XEiJ.regCCR = l << 1 == 0L ? XEiJ.REG_CCR_Z : 0L <= l ? 0 : XEiJ.REG_CCR_N;  //NaNのときは0
   494:     } else {
   495:       //([int,int]→[long]→double)<=>0
   496:       double d = Double.longBitsToDouble ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1]);
   497:       XEiJ.regCCR = d < 0.0 ? XEiJ.REG_CCR_N : d == 0.0 ? XEiJ.REG_CCR_Z : 0;  //NaNのときは0
   498:     }
   499:   }  //fpkDTST()
   500: 
   501:   //fpkDCMP ()
   502:   //  $FE29  __DCMP
   503:   //  64bit浮動小数点数の比較
   504:   //  x<=>y
   505:   //  バグ
   506:   //    FLOAT2.X 2.02/2.03はNaNがNaNと等しく、NaN以外のすべての数よりも大きい
   507:   //    FLOAT4.X 1.02はNaNがNaNと等しく、NaN以外のすべての数よりも大きい
   508:   //    FLOAT2.X 2.02/2.03は-0が0よりも小さい
   509:   //    FLOAT4.X 1.02は-0が0よりも小さい
   510:   //  <d0d1.d:64bit浮動小数点数。x
   511:   //  <d2d3.d:64bit浮動小数点数。y
   512:   //  >ccr:lt=x<y,eq=x==y,gt=x>y
   513:   public static void fpkDCMP () {
   514:     //([int,int]→[long]→double)<=>([int,int]→[long]→double)
   515:     double xd = Double.longBitsToDouble ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1]);
   516:     double yd = Double.longBitsToDouble ((long) XEiJ.regRn[2] << 32 | 0xffffffffL & XEiJ.regRn[3]);
   517:     XEiJ.regCCR = xd < yd ? XEiJ.REG_CCR_N | XEiJ.REG_CCR_C : xd == yd ? XEiJ.REG_CCR_Z : 0;  //どちらかがNaNのときは0
   518:   }  //fpkDCMP()
   519: 
   520:   //fpkDNEG ()
   521:   //  $FE2A  __DNEG
   522:   //  64bit浮動小数点数の符号反転
   523:   //  バグ
   524:   //    FLOAT2.X 2.02/2.03は-(+0)が+0になる
   525:   //    FLOAT4.X 1.02は-(+0)が+0になる
   526:   //    FLOAT2.X 2.02/2.03は-NaNが0xffffffffffffffffLになる
   527:   //    FLOAT4.X 1.02は-NaNが0xffffffffffffffffLになる
   528:   //    FLOAT2.X 2.02/2.03は-0x0000000000000001Lが0x0000000000000001Lになる
   529:   //    FLOAT4.X 1.02は-0x0000000000000001Lが0x0000000000000001Lになる
   530:   //  <d0d1.d:64bit浮動小数点数。x
   531:   //  >d0d1.d:64bit浮動小数点数。-x
   532:   public static void fpkDNEG () {
   533:     //-([int,int]→[long]→double)→[long]→[int,int]
   534:     long l = Double.doubleToLongBits (-Double.longBitsToDouble ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1]));
   535:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
   536:       l = 0x7fffffffffffffffL;
   537:     }
   538:     XEiJ.regRn[0] = (int) (l >>> 32);
   539:     XEiJ.regRn[1] = (int) l;
   540:   }  //fpkDNEG()
   541: 
   542:   //fpkDADD ()
   543:   //  $FE2B  __DADD
   544:   //  64bit浮動小数点数の加算
   545:   //  バグ
   546:   //    FLOAT2.X 2.02/2.03はNaNを+Infとして計算する。(+Inf)+(-Inf)はNaNになる
   547:   //    FLOAT2.X 2.02/2.03は丸めの処理がおかしい
   548:   //      0x3ff0000000000004+0x4024000000000000=0x4026000000000000が0x4026000000000001になる
   549:   //      0xbff921fb54442d18+0x40c3880000000000=0x40c38736f0255ddfが0x40c38736f0255ddeになる
   550:   //  <d0d1.d:64bit浮動小数点数。被加算数x
   551:   //  <d2d3.d:64bit浮動小数点数。加算数y
   552:   //  >d0d1.d:64bit浮動小数点数。和x+y
   553:   //  >ccr:cs=エラー,vs=オーバーフロー
   554:   public static void fpkDADD () {
   555:     //([int,int]→[long]→double)+([int,int]→[long]→double)→[long]→[int,int]
   556:     double xd = Double.longBitsToDouble ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1]);
   557:     double yd = Double.longBitsToDouble ((long) XEiJ.regRn[2] << 32 | 0xffffffffL & XEiJ.regRn[3]);
   558:     double zd = xd + yd;
   559:     long l = Double.doubleToLongBits (zd);
   560:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
   561:       l = 0x7fffffffffffffffL;
   562:     }
   563:     XEiJ.regRn[0] = (int) (l >>> 32);
   564:     XEiJ.regRn[1] = (int) l;
   565:     XEiJ.regCCR = (Double.isNaN (xd) || Double.isNaN (yd) ? 0 :  //引数がNaN
   566:            Double.isNaN (zd) ? XEiJ.REG_CCR_C :  //引数がNaNでないのに結果がNaNのときはエラー。(+Inf)+(-Inf)=NaN
   567:            Double.isInfinite (xd) || Double.isInfinite (yd) ? 0 :  //引数が±Inf
   568:            Double.isInfinite (zd) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C :  //引数が±Infでないのに結果が±Infのときはオーバーフロー
   569:            0);
   570:   }  //fpkDADD()
   571: 
   572:   //fpkDSUB ()
   573:   //  $FE2C  __DSUB
   574:   //  64bit浮動小数点数の減算
   575:   //  バグ
   576:   //    FLOAT2.X 2.02/2.03は丸めの処理がおかしい
   577:   //  <d0d1.d:64bit浮動小数点数。被減算数x
   578:   //  <d2d3.d:64bit浮動小数点数。減算数y
   579:   //  >d0d1.d:64bit浮動小数点数。差x-y
   580:   //  >ccr:cs=エラー,vs=オーバーフロー
   581:   public static void fpkDSUB () {
   582:     //([int,int]→[long]→double)-([int,int]→[long]→double)→[long]→[int,int]
   583:     double xd = Double.longBitsToDouble ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1]);
   584:     double yd = Double.longBitsToDouble ((long) XEiJ.regRn[2] << 32 | 0xffffffffL & XEiJ.regRn[3]);
   585:     double zd = xd - yd;
   586:     long l = Double.doubleToLongBits (zd);
   587:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
   588:       l = 0x7fffffffffffffffL;
   589:     }
   590:     XEiJ.regRn[0] = (int) (l >>> 32);
   591:     XEiJ.regRn[1] = (int) l;
   592:     XEiJ.regCCR = (Double.isNaN (xd) || Double.isNaN (yd) ? 0 :  //引数がNaN
   593:            Double.isNaN (zd) ? XEiJ.REG_CCR_C :  //引数がNaNでないのに結果がNaNのときはエラー。(+Inf)-(+Inf)=NaN
   594:            Double.isInfinite (xd) || Double.isInfinite (yd) ? 0 :  //引数が±Inf
   595:            Double.isInfinite (zd) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C :  //引数が±Infでないのに結果が±Infのときはオーバーフロー
   596:            0);
   597:   }  //fpkDSUB()
   598: 
   599:   //fpkDMUL ()
   600:   //  $FE2D  __DMUL
   601:   //  64bit浮動小数点数の乗算
   602:   //  バグ
   603:   //    FLOAT2.X 2.02/2.03は(+Inf)*(非正規化数)=(+Inf)がNaNになる
   604:   //    FLOAT2.X 2.02/2.03は(+x)*(非正規化数)=(+x)が+0になる
   605:   //    FLOAT2.X 2.02/2.03は(+x)*(-0)=(-0)が+0になる
   606:   //  <d0d1.d:64bit浮動小数点数。被乗数x
   607:   //  <d2d3.d:64bit浮動小数点数。乗数y
   608:   //  >d0d1.d:64bit浮動小数点数。積x*y
   609:   //  >ccr:cs=エラー,vs=オーバーフロー
   610:   public static void fpkDMUL () {
   611:     //([int,int]→[long]→double)*([int,int]→[long]→double)→[long]→[int,int]
   612:     double xd = Double.longBitsToDouble ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1]);
   613:     double yd = Double.longBitsToDouble ((long) XEiJ.regRn[2] << 32 | 0xffffffffL & XEiJ.regRn[3]);
   614:     double zd = xd * yd;
   615:     long l = Double.doubleToLongBits (zd);
   616:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
   617:       l = 0x7fffffffffffffffL;
   618:     }
   619:     XEiJ.regRn[0] = (int) (l >>> 32);
   620:     XEiJ.regRn[1] = (int) l;
   621:     XEiJ.regCCR = (Double.isNaN (xd) || Double.isNaN (yd) ? 0 :  //引数がNaN
   622:            Double.isNaN (zd) ? XEiJ.REG_CCR_C :  //引数がNaNでないのに結果がNaNのときはエラー。(±0)*(±Inf)=NaN
   623:            Double.isInfinite (xd) || Double.isInfinite (yd) ? 0 :  //引数が±Inf
   624:            Double.isInfinite (zd) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C :  //引数が±Infでないのに結果が±Infのときはオーバーフロー
   625:            0);
   626:   }  //fpkDMUL()
   627: 
   628:   //fpkDDIV ()
   629:   //  $FE2E  __DDIV
   630:   //  64bit浮動小数点数の除算
   631:   //  <d0d1.d:64bit浮動小数点数。被除数x
   632:   //  <d2d3.d:64bit浮動小数点数。除数y
   633:   //  >d0d1.d:64bit浮動小数点数。商x/y。ゼロ除算のときは不定
   634:   //  >ccr:cs=エラー,eq=ゼロ除算,vs=オーバーフロー
   635:   public static void fpkDDIV () {
   636:     //([int,int]→[long]→double)/([int,int]→[long]→double)→[long]→[int,int]
   637:     double xd = Double.longBitsToDouble ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1]);
   638:     double yd = Double.longBitsToDouble ((long) XEiJ.regRn[2] << 32 | 0xffffffffL & XEiJ.regRn[3]);
   639:     double zd = xd / yd;
   640:     long l = Double.doubleToLongBits (zd);
   641:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
   642:       l = 0x7fffffffffffffffL;
   643:     }
   644:     XEiJ.regRn[0] = (int) (l >>> 32);
   645:     XEiJ.regRn[1] = (int) l;
   646:     XEiJ.regCCR = (Double.isNaN (xd) || Double.isNaN (yd) ? 0 :  //引数がNaN
   647:            Double.isNaN (zd) ? XEiJ.REG_CCR_C :  //引数がNaNでないのに結果がNaNのときはエラー。(±0)/(±0)=NaN
   648:            Double.isInfinite (xd) || Double.isInfinite (yd) ? 0 :  //引数が±Inf。(±Inf)/(±0)=(±Inf)
   649:            yd == 0.0 ? XEiJ.REG_CCR_Z | XEiJ.REG_CCR_C :  //除数が±0のときはゼロ除算
   650:            Double.isInfinite (zd) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C :  //引数が±Infでないのに結果が±Infのときはオーバーフロー
   651:            0);
   652:   }  //fpkDDIV()
   653: 
   654:   //fpkDMOD ()
   655:   //  $FE2F  __DMOD
   656:   //  64bit浮動小数点数の剰余算
   657:   //  バグ
   658:   //    FLOAT4.X 1.02はNaN%0がエラーになる
   659:   //  <d0d1.d:64bit浮動小数点数。被除数x
   660:   //  <d2d3.d:64bit浮動小数点数。除数y
   661:   //  >d0d1.d:64bit浮動小数点数。余りx%y。ゼロ除算のときは不定
   662:   //  >ccr:cs=エラー,eq=ゼロ除算
   663:   public static void fpkDMOD () {
   664:     //([int,int]→[long]→double)%([int,int]→[long]→double)→[long]→[int,int]
   665:     double xd = Double.longBitsToDouble ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1]);
   666:     double yd = Double.longBitsToDouble ((long) XEiJ.regRn[2] << 32 | 0xffffffffL & XEiJ.regRn[3]);
   667:     double zd = xd % yd;
   668:     long l = Double.doubleToLongBits (zd);
   669:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
   670:       l = 0x7fffffffffffffffL;
   671:     }
   672:     XEiJ.regRn[0] = (int) (l >>> 32);
   673:     XEiJ.regRn[1] = (int) l;
   674:     XEiJ.regCCR = (Double.isNaN (xd) || Double.isNaN (yd) ? 0 :  //引数がNaN
   675:            yd == 0.0 ? XEiJ.REG_CCR_Z | XEiJ.REG_CCR_C :  //除数が0のときはゼロ除算。(±Inf)%(±0)=NaN, x%(±0)=(±Inf)
   676:            Double.isNaN (zd) ? XEiJ.REG_CCR_C :  //引数がNaNでないのに結果がNaNのときはエラー。(±Inf)%y=NaN
   677:            Double.isInfinite (xd) || Double.isInfinite (yd) ? 0 :  //引数が±Inf
   678:            Double.isInfinite (zd) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C :  //引数が±Infでないのに結果が±Infのときはオーバーフロー
   679:            0);
   680:   }  //fpkDMOD()
   681: 
   682:   //fpkDABS ()
   683:   //  $FE30  __DABS
   684:   //  64bit浮動小数点数の絶対値
   685:   //  <d0d1.d:64bit浮動小数点数。x
   686:   //  >d0d1.d:64bit浮動小数点数。abs(x)
   687:   public static void fpkDABS () {
   688:     //abs([int,int]→[long]→double)→[long]→[int,int]
   689:     long l = Double.doubleToLongBits (Math.abs (Double.longBitsToDouble ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1])));
   690:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
   691:       l = 0x7fffffffffffffffL;
   692:     }
   693:     XEiJ.regRn[0] = (int) (l >>> 32);
   694:     XEiJ.regRn[1] = (int) l;
   695:   }  //fpkDABS()
   696: 
   697:   //fpkDCEIL ()
   698:   //  $FE31  __DCEIL
   699:   //  64bit浮動小数点数の天井関数(引数を下回らない最小の整数)
   700:   //  バグ
   701:   //    FLOAT2.X 2.02/2.03はCEIL(-0)やCEIL(-0.5)が+0になる
   702:   //  <d0d1.d:64bit浮動小数点数。x
   703:   //  >d0d1.d:64bit浮動小数点数。ceil(x)
   704:   public static void fpkDCEIL () {
   705:     //ceil([int,int]→[long]→double)→[long]→[int,int]
   706:     long l = Double.doubleToLongBits (Math.ceil (Double.longBitsToDouble ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1])));
   707:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
   708:       l = 0x7fffffffffffffffL;
   709:     }
   710:     XEiJ.regRn[0] = (int) (l >>> 32);
   711:     XEiJ.regRn[1] = (int) l;
   712:   }  //fpkDCEIL()
   713: 
   714:   //fpkDFIX ()
   715:   //  $FE32  __DFIX
   716:   //  64bit浮動小数点数の切り落とし関数(絶対値について引数を上回らない最大の整数)
   717:   //  バグ
   718:   //    FLOAT2.X 2.02/2.03はFIX(-0)やFIX(-0.5)が+0になる
   719:   //  <d0d1.d:64bit浮動小数点数。x
   720:   //  >d0d1.d:64bit浮動小数点数。trunc(x)
   721:   public static void fpkDFIX () {
   722:     //trunc([int,int]→[long]→double)→[long]→[int,int]
   723:     double d = Double.longBitsToDouble ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1]);
   724:     long l = Double.doubleToLongBits (0.0 <= d ? Math.floor (d) : Math.ceil (d));  //0<=-0だがMath.floor(-0)=-0なので問題ない
   725:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
   726:       l = 0x7fffffffffffffffL;
   727:     }
   728:     XEiJ.regRn[0] = (int) (l >>> 32);
   729:     XEiJ.regRn[1] = (int) l;
   730:   }  //fpkDFIX()
   731: 
   732:   //fpkDFLOOR ()
   733:   //  $FE33  __DFLOOR
   734:   //  64bit浮動小数点数の床関数(引数を上回らない最大の整数)
   735:   //  バグ
   736:   //    FLOAT2.X 2.02/2.03はFLOOR(-0)が-1になる
   737:   //  <d0d1.d:64bit浮動小数点数。x
   738:   //  >d0d1.d:64bit浮動小数点数。floor(x)
   739:   public static void fpkDFLOOR () {
   740:     //floor([int,int]→[long]→double)→[long]→[int,int]
   741:     long l = Double.doubleToLongBits (Math.floor (Double.longBitsToDouble ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1])));
   742:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
   743:       l = 0x7fffffffffffffffL;
   744:     }
   745:     XEiJ.regRn[0] = (int) (l >>> 32);
   746:     XEiJ.regRn[1] = (int) l;
   747:   }  //fpkDFLOOR()
   748: 
   749:   //fpkDFRAC ()
   750:   //  $FE34  __DFRAC
   751:   //  64bit浮動小数点数の幹小数部
   752:   //  メモ
   753:   //    FLOAT2.X 2.02/2.03はDFRAC(±Inf)が±0になる
   754:   //    同様の機能を持ったライブラリによってはfrac(±Inf)が引数の±Infをそのまま返すものもある
   755:   //    x-trunc(x)だとInf-Inf=NaNになる。trunc(x)+frac(x)がxに戻らないので都合が悪い場合があるかも知れない
   756:   //  バグ
   757:   //    FLOAT2.X 2.02/2.03はDFRAC(NaN)=NaNが0になる
   758:   //    FLOAT4.X 1.02はDFRAC(NaN)=NaNが0になる
   759:   //  <d0d1.d:64bit浮動小数点数。x
   760:   //  >d0d1.d:64bit浮動小数点数。frac(x)=copysign(x-trunc(x),x)
   761:   public static void fpkDFRAC () {
   762:     //frac([int,int]→[long]→double)→[long]→[int,int]
   763:     long l = (long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1];
   764:     double d = Double.longBitsToDouble (l);
   765:     l = (Double.isNaN (d) ? Double.doubleToLongBits (Double.NaN) :  //frac(NaN)=NaN
   766:          Double.isInfinite (d) ? l & 0x8000000000000000L :  //frac(±Inf)=±0
   767:          Double.doubleToLongBits (0L <= l ? d - Math.floor (d) : -(-d - Math.floor (-d))));  //0<=-0なので0<=d?~は不可
   768:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
   769:       l = 0x7fffffffffffffffL;
   770:     }
   771:     XEiJ.regRn[0] = (int) (l >>> 32);
   772:     XEiJ.regRn[1] = (int) l;
   773:   }  //fpkDFRAC()
   774: 
   775:   //fpkDSGN ()
   776:   //  $FE35  __DSGN
   777:   //  64bit浮動小数点数の符号
   778:   //  バグ
   779:   //    FLOAT2.X 2.02/2.03はDSGN(-0)=-0が+0になる
   780:   //    FLOAT4.X 1.02はDSGN(-0)=-0が+0になる
   781:   //    FLOAT4.X 1.02はDSGN(NaN)=NaNが+1になる
   782:   //  <d0d1.d:64bit浮動小数点数。x
   783:   //  >d0d1.d:64bit浮動小数点数。signum(x)
   784:   public static void fpkDSGN () {
   785:     //signum([int,int]→[long]→double)→[long]→[int,int]
   786:     long l = Double.doubleToLongBits (Math.signum (Double.longBitsToDouble ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1])));
   787:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
   788:       l = 0x7fffffffffffffffL;
   789:     }
   790:     XEiJ.regRn[0] = (int) (l >>> 32);
   791:     XEiJ.regRn[1] = (int) l;
   792:   }  //fpkDSGN()
   793: 
   794:   //fpkSIN ()
   795:   //  $FE36  __SIN
   796:   //  64bit浮動小数点数の正弦
   797:   //  バグ
   798:   //    FLOAT2.X 2.02/2.03はsin(x)でxの絶対値が大きすぎるとき真の値からかけ離れた結果を返す
   799:   //  <d0d1.d:64bit浮動小数点数。x
   800:   //  >d0d1.d:64bit浮動小数点数。sin(x)
   801:   //  >ccr:x=±Inf。C以外は不定
   802:   public static void fpkSIN () {
   803:     //sin([int,int]→[long]→double)→[long]→[int,int]
   804:     double xd = Double.longBitsToDouble ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1]);
   805:     double zd = Math.sin (xd);
   806:     long l = Double.doubleToLongBits (zd);
   807:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
   808:       l = 0x7fffffffffffffffL;
   809:     }
   810:     XEiJ.regRn[0] = (int) (l >>> 32);
   811:     XEiJ.regRn[1] = (int) l;
   812:     XEiJ.regCCR = !Double.isNaN (xd) && Double.isNaN (zd) ? XEiJ.REG_CCR_C : 0;  //引数がNaNでないのに結果がNaNのときはエラー。sin(±Inf)=NaN
   813:   }  //fpkSIN()
   814: 
   815:   //fpkCOS ()
   816:   //  $FE37  __COS
   817:   //  64bit浮動小数点数の余弦
   818:   //  バグ
   819:   //    FLOAT2.X 2.02/2.03はcos(x)でxの絶対値が大きすぎるとき真の値からかけ離れた結果を返す
   820:   //  <d0d1.d:64bit浮動小数点数。x
   821:   //  >d0d1.d:64bit浮動小数点数。cos(x)
   822:   //  >ccr:x=±Inf。C以外は不定
   823:   public static void fpkCOS () {
   824:     //cos([int,int]→[long]→double)→[long]→[int,int]
   825:     double xd = Double.longBitsToDouble ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1]);
   826:     double zd = Math.cos (xd);
   827:     long l = Double.doubleToLongBits (zd);
   828:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
   829:       l = 0x7fffffffffffffffL;
   830:     }
   831:     XEiJ.regRn[0] = (int) (l >>> 32);
   832:     XEiJ.regRn[1] = (int) l;
   833:     XEiJ.regCCR = !Double.isNaN (xd) && Double.isNaN (zd) ? XEiJ.REG_CCR_C : 0;  //引数がNaNでないのに結果がNaNのときはエラー。cos(±Inf)=NaN
   834:   }  //fpkCOS()
   835: 
   836:   //fpkTAN ()
   837:   //  $FE38  __TAN
   838:   //  64bit浮動小数点数の正接
   839:   //  バグ
   840:   //    FLOAT2.X 2.02/2.03はtan(x)でxの絶対値が大きすぎるとき真の値からかけ離れた結果を返す
   841:   //  <d0d1.d:64bit浮動小数点数。x
   842:   //  >d0d1.d:64bit浮動小数点数。tan(x)
   843:   //  >ccr:x=±Inf。C以外は不定
   844:   public static void fpkTAN () {
   845:     //tan([int,int]→[long]→double)→[long]→[int,int]
   846:     double xd = Double.longBitsToDouble ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1]);
   847:     double zd = Math.tan (xd);
   848:     long l = Double.doubleToLongBits (zd);
   849:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
   850:       l = 0x7fffffffffffffffL;
   851:     }
   852:     XEiJ.regRn[0] = (int) (l >>> 32);
   853:     XEiJ.regRn[1] = (int) l;
   854:     XEiJ.regCCR = !Double.isNaN (xd) && Double.isNaN (zd) ? XEiJ.REG_CCR_C : 0;  //引数がNaNでないのに結果がNaNのときはエラー。tan(±Inf)=NaN
   855:   }  //fpkTAN()
   856: 
   857:   //fpkATAN ()
   858:   //  $FE39  __ATAN
   859:   //  64bit浮動小数点数の逆正接
   860:   //  バグ
   861:   //    FLOAT2.X 2.02/2.03は非正規化数を+0とみなす。__ATAN(0x000fffffffffffffL)が+0になる
   862:   //  <d0d1.d:64bit浮動小数点数。x
   863:   //  >d0d1.d:64bit浮動小数点数。atan(x)
   864:   public static void fpkATAN () {
   865:     //atan([int,int]→[long]→double)→[long]→[int,int]
   866:     long l = Double.doubleToLongBits (Math.atan (Double.longBitsToDouble ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1])));
   867:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
   868:       l = 0x7fffffffffffffffL;
   869:     }
   870:     XEiJ.regRn[0] = (int) (l >>> 32);
   871:     XEiJ.regRn[1] = (int) l;
   872:   }  //fpkATAN()
   873: 
   874:   //fpkLOG ()
   875:   //  $FE3A  __LOG
   876:   //  64bit浮動小数点数の自然対数
   877:   //  バグ
   878:   //    FLOAT2.X 2.02/2.03は非正規化数を+0とみなす。__LOG(0x000fffffffffffffL)が-InfになってXEiJ.REG_CCR_Cがセットされる
   879:   //    FLOAT2.X 2.02/2.03は__LOG(±0)でCがセットされるがZをセットしない
   880:   //  <d0d1.d:64bit浮動小数点数。x
   881:   //  >d0d1.d:64bit浮動小数点数。log(x)
   882:   //  >ccr:0=エラーなし,C=x<0,Z|C=x==0
   883:   public static void fpkLOG () {
   884:     //log([int,int]→[long]→double)→[long]→[int,int]
   885:     double xd = Double.longBitsToDouble ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1]);
   886:     double zd = Math.log (xd);
   887:     long l = Double.doubleToLongBits (zd);
   888:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
   889:       l = 0x7fffffffffffffffL;
   890:     }
   891:     XEiJ.regRn[0] = (int) (l >>> 32);
   892:     XEiJ.regRn[1] = (int) l;
   893:     XEiJ.regCCR = (Double.isNaN (xd) ? 0 :  //引数がNaN
   894:            Double.isNaN (zd) ? XEiJ.REG_CCR_C :  //引数がNaNでないのに結果がNaNのときはエラー。log(-x)=NaN
   895:            Double.isInfinite (xd) ? 0 :  //引数が±Inf
   896:            Double.isInfinite (zd) ? XEiJ.REG_CCR_Z | XEiJ.REG_CCR_C :  //引数が±Infでないのに結果が±Infのときはエラー。log(±0)=-Inf
   897:            0);
   898:   }  //fpkLOG()
   899: 
   900:   //fpkEXP ()
   901:   //  $FE3B  __EXP
   902:   //  64bit浮動小数点数の指数関数
   903:   //  <d0d1.d:64bit浮動小数点数。x
   904:   //  >d0d1.d:64bit浮動小数点数。exp(x)
   905:   //  >ccr:cs=オーバーフロー
   906:   public static void fpkEXP () {
   907:     //exp([int,int]→[long]→double)→[long]→[int,int]
   908:     int xh = XEiJ.regRn[0];
   909:     long l = Double.doubleToLongBits (Math.exp (Double.longBitsToDouble ((long) xh << 32 | 0xffffffffL & XEiJ.regRn[1])));
   910:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
   911:       l = 0x7fffffffffffffffL;
   912:     }
   913:     int zh = (int) (l >>> 32);
   914:     XEiJ.regRn[0] = zh;
   915:     XEiJ.regRn[1] = (int) l;
   916:     XEiJ.regCCR = (zh & 0x7ff00000) == 0x7ff00000 && (xh & 0x7ff00000) != 0x7ff00000 ? XEiJ.REG_CCR_C : 0;  //結果が±Inf,NaNだが引数が±Inf,NaNでなかったときはエラー
   917:   }  //fpkEXP()
   918: 
   919:   //fpkSQR ()
   920:   //  $FE3C  __SQR
   921:   //  64bit浮動小数点数の平方根
   922:   //  バグ
   923:   //    FLOAT4.X 1.02はSQR(-0)=-0が+0になる(実機で確認済み)
   924:   //    FLOAT4.X 1.02はSQR(0x8000000000000001)=NaNがNaNになるがエラーにならない(実機で確認済み)
   925:   //    FLOAT2.X 2.02/2.03は__SQR(0x0000000000000001)が+0になる
   926:   //      __SQR(0x000fffffffffffff)は0x1fffffffffffffffになるので非正規化数がすべて+0になるというわけではない
   927:   //  <d0d1.d:64bit浮動小数点数。x
   928:   //  >d0d1.d:64bit浮動小数点数。sqrt(x)
   929:   //  >ccr:cs=x<0
   930:   public static void fpkSQR () {
   931:     //sqrt([int,int]→[long]→double)→[long]→[int,int]
   932:     double xd = Double.longBitsToDouble ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1]);
   933:     long l = Double.doubleToLongBits (Math.sqrt (xd));
   934:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
   935:       l = 0x7fffffffffffffffL;
   936:     }
   937:     XEiJ.regRn[0] = (int) (l >>> 32);
   938:     XEiJ.regRn[1] = (int) l;
   939:     XEiJ.regCCR = xd < 0.0 ? XEiJ.REG_CCR_C : 0;  //NaNはエラーなし
   940:   }  //fpkSQR()
   941: 
   942:   //fpkPI ()
   943:   //  $FE3D  __PI
   944:   //  64bit浮動小数点数の円周率
   945:   //  >d0d1.d:64bit浮動小数点数。pi
   946:   public static void fpkPI () {
   947:     if (true) {
   948:       XEiJ.regRn[0] = 0x400921fb;
   949:       XEiJ.regRn[1] = 0x54442d18;
   950:     } else {
   951:       //pi→[long]→[int,int]
   952:       long l = Double.doubleToLongBits (Math.PI);
   953:       XEiJ.regRn[0] = (int) (l >>> 32);
   954:       XEiJ.regRn[1] = (int) l;
   955:     }
   956:   }  //fpkPI()
   957: 
   958:   //fpkNPI ()
   959:   //  $FE3E  __NPI
   960:   //  64bit浮動小数点数の円周率倍
   961:   //  メモ
   962:   //    FLOAT2.Xの__NPIは倍精度の円周率を倍精度で掛ける
   963:   //    FLOAT4.Xの__NPIは拡張精度の円周率を拡張精度で掛けて倍精度に丸める
   964:   //    乗算以前に円周率の値が違うので結果が一致しない場合が想像以上に多い
   965:   //  バグ
   966:   //    FLOAT2.X 2.02/2.03は非正規化数を+0とみなす。__NPI(0x000fffffffffffff)が+0になる
   967:   //  <d0d1.d:64bit浮動小数点数。x
   968:   //  >d0d1.d:64bit浮動小数点数。x*pi
   969:   //  >ccr:cs=オーバーフロー
   970:   public static void fpkNPI () {
   971:     //([int,int]→[long]→double)*pi→[long]→[int,int]
   972:     int xh = XEiJ.regRn[0];
   973:     //long l = Double.doubleToLongBits (Double.longBitsToDouble ((long) xh << 32 | 0xffffffffL & r[1]) * Math.PI);
   974:     //  四倍精度のπを四倍精度で掛けて倍精度に丸める
   975:     long l = Double.doubleToLongBits (new QFP (Double.longBitsToDouble ((long) xh << 32 | 0xffffffffL & XEiJ.regRn[1])).mul (QFP.QFP_PI).getd ());
   976:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
   977:       l = 0x7fffffffffffffffL;
   978:     }
   979:     int zh = (int) (l >>> 32);
   980:     XEiJ.regRn[0] = zh;
   981:     XEiJ.regRn[1] = (int) l;
   982:     XEiJ.regCCR = (zh & 0x7ff00000) == 0x7ff00000 && (xh & 0x7ff00000) != 0x7ff00000 ? XEiJ.REG_CCR_C : 0;  //結果が±Inf,NaNだが引数が±Inf,NaNでなかったときはエラー
   983:   }  //fpkNPI()
   984: 
   985:   //fpkPOWER ()
   986:   //  $FE3F  __POWER
   987:   //  64bit浮動小数点数の累乗
   988:   //  バグ
   989:   //    FLOAT4.X 1.02で(+Inf)^(-Inf)を計算しようとするとハングアップする(実機で確認済み)
   990:   //      movem.l d0-d1,-(sp)でd0d1.dを(sp).dで取り出せるようにした後、
   991:   //      spを復元せずにrtsで復帰しようとして0x00f00000にあるCGROMにジャンプしている
   992:   //  <d0d1.d:64bit浮動小数点数。x
   993:   //  <d2d3.d:64bit浮動小数点数。y
   994:   //  >d0d1.d:64bit浮動小数点数。pow(x,y)
   995:   //  >ccr:cs=オーバーフロー
   996:   public static void fpkPOWER () {
   997:     //pow([int,int]→[long]→double,[int,int]→[long]→double)→[long]→[int,int]
   998:     double xd = Double.longBitsToDouble ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1]);
   999:     double yd = Double.longBitsToDouble ((long) XEiJ.regRn[2] << 32 | 0xffffffffL & XEiJ.regRn[3]);
  1000:     double zd = Math.pow (xd, yd);
  1001:     long l = Double.doubleToLongBits (zd);
  1002:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
  1003:       l = 0x7fffffffffffffffL;
  1004:     }
  1005:     XEiJ.regRn[0] = (int) (l >>> 32);
  1006:     XEiJ.regRn[1] = (int) l;
  1007:     XEiJ.regCCR = (Double.isNaN (xd) || Double.isNaN (yd) ? 0 :  //引数がNaN
  1008:            Double.isNaN (zd) ? XEiJ.REG_CCR_C :  //引数がNaNでないのに結果がNaNのときはエラー
  1009:            Double.isInfinite (xd) || Double.isInfinite (yd) ? 0 :  //引数が±Inf
  1010:            Double.isInfinite (zd) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C :  //引数が±Infでないのに結果が±Infのときはオーバーフロー
  1011:            0);
  1012:   }  //fpkPOWER()
  1013: 
  1014:   //fpkRND ()
  1015:   //  $FE40  __RND
  1016:   //  64bit浮動小数点数の乱数
  1017:   //  >d0d1.d:64bit浮動小数点数。rnd()。0以上1未満
  1018:   public static void fpkRND () {
  1019:     long l = 0xffffffffL & fpkRndLong ();  //下位
  1020:     l |= (0x001fffffL & fpkRndLong ()) << 32;  //上位。順序に注意
  1021:     //  ここでl==0LのときLong.numberOfLeadingZeros(z)==64なので乱数の値は2^-54になる
  1022:     //  FLOATn.Xはその場合を考慮しておらず0のときも先頭の1のビットを探し続けて無限ループに陥ると思われる
  1023:     //  実際に0が53ビット並ぶことはないかも知れない
  1024:     int o = Long.numberOfLeadingZeros (l) - 11;
  1025:     l = (long) (0x3fe - o) << 52 | 0x000fffffffffffffL & l << o;
  1026:     XEiJ.regRn[0] = (int) (l >>> 32);
  1027:     XEiJ.regRn[1] = (int) l;
  1028:   }  //fpkRND()
  1029: 
  1030:   //fpkSINH ()
  1031:   //  $FE41  __SINH
  1032:   //  64bit浮動小数点数の双曲線正弦
  1033:   //  バグ
  1034:   //    FLOAT2.X 2.02/2.03は__SINH(NaN)がエラーになる
  1035:   //    FLOAT2.X 2.02/2.03は|x|<1.5/2^53のとき__SINH(x)が0になる
  1036:   //      sinh(x)=(exp(x)-1/exp(x))/2だけで計算しており、x≒0のとき情報落ちでexp(x)≒1+x≒1となることが考慮されていない
  1037:   //      sinh(0x3ca8000000000000)=0x3ca8000000000000=1.5/2^53
  1038:   //      sinh(0x3ca7ffffffffffff)=0x0000000000000000  ここから突然0になる
  1039:   //    FLOAT2.X 2.02/2.03はx<-6243314768165359/274877906944=-22713.0468…のときVがセットされない
  1040:   //      sinh(0xc0d62e42fefa39ef)はV|C
  1041:   //      sinh(0xc0d62e42fefa39f0)はC
  1042:   //      exp(x)がアンダーフローした時点でエラー終了してしまいオーバーフローするexp(-x)を計算していない
  1043:   //      この場合はアンダーフローした側を0として扱うべき
  1044:   //  <d0d1.d:64bit浮動小数点数。x
  1045:   //  >d0d1.d:64bit浮動小数点数。sinh(x)
  1046:   //  >ccr:cs=エラー,vs=オーバーフロー
  1047:   public static void fpkSINH () {
  1048:     //sinh([int,int]→[long]→double)→[long]→[int,int]
  1049:     double xd = Double.longBitsToDouble ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1]);
  1050:     double zd = Math.sinh (xd);
  1051:     long l = Double.doubleToLongBits (zd);
  1052:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
  1053:       l = 0x7fffffffffffffffL;
  1054:     }
  1055:     XEiJ.regRn[0] = (int) (l >>> 32);
  1056:     XEiJ.regRn[1] = (int) l;
  1057:     XEiJ.regCCR = (Double.isNaN (xd) ? 0 :  //引数がNaN
  1058:            Double.isNaN (zd) ? XEiJ.REG_CCR_C :  //引数がNaNでないのに結果がNaNのときはエラー
  1059:            Double.isInfinite (xd) ? 0 :  //引数が±Inf
  1060:            Double.isInfinite (zd) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C :  //引数が±Infでないのに結果が±Infのときはオーバーフロー
  1061:            0);
  1062:   }  //fpkSINH()
  1063: 
  1064:   //fpkCOSH ()
  1065:   //  $FE42  __COSH
  1066:   //  64bit浮動小数点数の双曲線余弦
  1067:   //  バグ
  1068:   //    FLOAT2.X 2.02/2.03はCOSH(NaN)=NaNが+Infになる
  1069:   //  <d0d1.d:64bit浮動小数点数。x
  1070:   //  >d0d1.d:64bit浮動小数点数。cosh(x)
  1071:   //  >ccr:cs=エラー,vs=オーバーフロー
  1072:   public static void fpkCOSH () {
  1073:     //cosh([int,int]→[long]→double)→[long]→[int,int]
  1074:     double xd = Double.longBitsToDouble ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1]);
  1075:     double zd = Math.cosh (xd);
  1076:     long l = Double.doubleToLongBits (zd);
  1077:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
  1078:       l = 0x7fffffffffffffffL;
  1079:     }
  1080:     XEiJ.regRn[0] = (int) (l >>> 32);
  1081:     XEiJ.regRn[1] = (int) l;
  1082:     XEiJ.regCCR = (Double.isNaN (xd) ? 0 :  //引数がNaN
  1083:            Double.isNaN (zd) ? XEiJ.REG_CCR_C :  //引数がNaNでないのに結果がNaNのときはエラー
  1084:            Double.isInfinite (xd) ? 0 :  //引数が±Inf
  1085:            Double.isInfinite (zd) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C :  //引数が±Infでないのに結果が±Infのときはオーバーフロー
  1086:            0);
  1087:   }  //fpkCOSH()
  1088: 
  1089:   //fpkTANH ()
  1090:   //  $FE43  __TANH
  1091:   //  64bit浮動小数点数の双曲線正接
  1092:   //  <d0d1.d:64bit浮動小数点数。x
  1093:   //  >d0d1.d:64bit浮動小数点数。tanh(x)
  1094:   public static void fpkTANH () {
  1095:     //tanh([int,int]→[long]→double)→[long]→[int,int]
  1096:     long l = Double.doubleToLongBits (Math.tanh (Double.longBitsToDouble ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1])));
  1097:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
  1098:       l = 0x7fffffffffffffffL;
  1099:     }
  1100:     XEiJ.regRn[0] = (int) (l >>> 32);
  1101:     XEiJ.regRn[1] = (int) l;
  1102:   }  //fpkTANH()
  1103: 
  1104:   //fpkATANH ()
  1105:   //  $FE44  __ATANH
  1106:   //  64bit浮動小数点数の逆双曲線正接
  1107:   //  <d0d1.d:64bit浮動小数点数。x
  1108:   //  >d0d1.d:64bit浮動小数点数。atanh(x)
  1109:   //  >ccr:cs=x<=-1||1<=x
  1110:   public static void fpkATANH () {
  1111:     //atanh([int,int]→[long]→double)→[long]→[int,int]
  1112:     double d = Double.longBitsToDouble ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1]);
  1113:     if (true) {
  1114:       QFP.fpsr = 0;
  1115:       d = new QFP (d).atanh ().getd ();
  1116:       XEiJ.regCCR = (QFP.fpsr & (QFP.QFP_OE | QFP.QFP_DZ)) != 0 ? XEiJ.REG_CCR_C : 0;
  1117:     } else {
  1118:       double s = Math.signum (d);
  1119:       double a = Math.abs (d);
  1120:       if (a < 1.0) {
  1121:         d = s * (Math.log1p (a) - Math.log1p (-a)) * 0.5;  //Math.atanh(double)がない
  1122:         XEiJ.regCCR = 0;
  1123:       } else if (a == 1.0) {
  1124:         d = s * Double.POSITIVE_INFINITY;
  1125:         XEiJ.regCCR = XEiJ.REG_CCR_C;
  1126:       } else {
  1127:         d = Double.NaN;
  1128:         XEiJ.regCCR = XEiJ.REG_CCR_C;
  1129:       }
  1130:     }
  1131:     long l = Double.doubleToLongBits (d);
  1132:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
  1133:       l = 0x7fffffffffffffffL;
  1134:     }
  1135:     XEiJ.regRn[0] = (int) (l >>> 32);
  1136:     XEiJ.regRn[1] = (int) l;
  1137:   }  //fpkATANH()
  1138: 
  1139:   //fpkASIN ()
  1140:   //  $FE45  __ASIN
  1141:   //  64bit浮動小数点数の逆正弦
  1142:   //  <d0d1.d:64bit浮動小数点数。x
  1143:   //  >d0d1.d:64bit浮動小数点数。asin(x)
  1144:   //  >ccr:cs=x<-1||1<x
  1145:   public static void fpkASIN () {
  1146:     //asin([int,int]→[long]→double)→[long]→[int,int]
  1147:     double d = Double.longBitsToDouble ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1]);
  1148:     if (d < -1.0 || 1.0 < d) {  //定義域の外。±1,NaNを含まない
  1149:       d = Double.NaN;
  1150:       XEiJ.regCCR = XEiJ.REG_CCR_C;
  1151:     } else {  //定義域の中。±1,NaNを含む
  1152:       d = Math.asin (d);
  1153:       XEiJ.regCCR = 0;
  1154:     }
  1155:     long l = Double.doubleToLongBits (d);
  1156:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
  1157:       l = 0x7fffffffffffffffL;
  1158:     }
  1159:     XEiJ.regRn[0] = (int) (l >>> 32);
  1160:     XEiJ.regRn[1] = (int) l;
  1161:   }  //fpkASIN()
  1162: 
  1163:   //fpkACOS ()
  1164:   //  $FE46  __ACOS
  1165:   //  64bit浮動小数点数の逆余弦
  1166:   //  <d0d1.d:64bit浮動小数点数。x
  1167:   //  >d0d1.d:64bit浮動小数点数。acos(x)
  1168:   //  >ccr:cs=x<-1||1<x
  1169:   public static void fpkACOS () {
  1170:     //acos([int,int]→[long]→double)→[long]→[int,int]
  1171:     double d = Double.longBitsToDouble ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1]);
  1172:     if (d < -1.0 || 1.0 < d) {  //定義域の外。±1,NaNを含まない
  1173:       d = Double.NaN;
  1174:       XEiJ.regCCR = XEiJ.REG_CCR_C;
  1175:     } else {  //定義域の中。±1,NaNを含む
  1176:       d = Math.acos (d);
  1177:       XEiJ.regCCR = 0;
  1178:     }
  1179:     long l = Double.doubleToLongBits (d);
  1180:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
  1181:       l = 0x7fffffffffffffffL;
  1182:     }
  1183:     XEiJ.regRn[0] = (int) (l >>> 32);
  1184:     XEiJ.regRn[1] = (int) l;
  1185:   }  //fpkACOS()
  1186: 
  1187:   //fpkLOG10 ()
  1188:   //  $FE47  __LOG10
  1189:   //  64bit浮動小数点数の常用対数
  1190:   //  <d0d1.d:64bit浮動小数点数。x
  1191:   //  >d0d1.d:64bit浮動小数点数。log10(x)
  1192:   //  >ccr:0=エラーなし,C=x<0,Z|C=x==0
  1193:   public static void fpkLOG10 () {
  1194:     //log10([int,int]→[long]→double)→[long]→[int,int]
  1195:     double xd = Double.longBitsToDouble ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1]);
  1196:     double zd = Math.log10 (xd);
  1197:     long l = Double.doubleToLongBits (zd);
  1198:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
  1199:       l = 0x7fffffffffffffffL;
  1200:     }
  1201:     XEiJ.regRn[0] = (int) (l >>> 32);
  1202:     XEiJ.regRn[1] = (int) l;
  1203:     XEiJ.regCCR = (Double.isNaN (xd) ? 0 :  //引数がNaN
  1204:            Double.isNaN (zd) ? XEiJ.REG_CCR_C :  //引数がNaNでないのに結果がNaNのときはエラー。log10(-x)=NaN
  1205:            Double.isInfinite (xd) ? 0 :  //引数が±Inf
  1206:            Double.isInfinite (zd) ? XEiJ.REG_CCR_Z | XEiJ.REG_CCR_C :  //引数が±Infでないのに結果が±Infのときはエラー。log10(±0)=-Inf
  1207:            0);
  1208:   }  //fpkLOG10()
  1209: 
  1210:   //fpkLOG2 ()
  1211:   //  $FE48  __LOG2
  1212:   //  64bit浮動小数点数の二進対数
  1213:   //  <d0d1.d:64bit浮動小数点数。x
  1214:   //  >d0d1.d:64bit浮動小数点数。log2(x)
  1215:   //  >ccr:0=エラーなし,C=x<0,Z|C=x==0
  1216:   public static void fpkLOG2 () {
  1217:     //log2([int,int]→[long]→double)→[long]→[int,int]
  1218:     double xd = Double.longBitsToDouble ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1]);
  1219:     double zd = Math.log (xd) / 0.69314718055994530941723212146;  //log(2)。Math.log2(double)がない
  1220:     long l = Double.doubleToLongBits (zd);
  1221:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
  1222:       l = 0x7fffffffffffffffL;
  1223:     }
  1224:     XEiJ.regRn[0] = (int) (l >>> 32);
  1225:     XEiJ.regRn[1] = (int) l;
  1226:     XEiJ.regCCR = (Double.isNaN (xd) ? 0 :  //引数がNaN
  1227:            Double.isNaN (zd) ? XEiJ.REG_CCR_C :  //引数がNaNでないのに結果がNaNのときはエラー。log2(-x)=NaN
  1228:            Double.isInfinite (xd) ? 0 :  //引数が±Inf
  1229:            Double.isInfinite (zd) ? XEiJ.REG_CCR_Z | XEiJ.REG_CCR_C :  //引数が±Infでないのに結果が±Infのときはエラー。log2(±0)=-Inf
  1230:            0);
  1231:   }  //fpkLOG2()
  1232: 
  1233:   //fpkDFREXP ()
  1234:   //  $FE49  __DFREXP
  1235:   //  64bit浮動小数点数の分解
  1236:   //  <d0d1.d:64bit浮動小数点数。x
  1237:   //  >d0d1.d:xの指数部を0にした値。x==0のときは0
  1238:   //  >d2.l:xの指数部。x==0のときは0
  1239:   public static void fpkDFREXP () {
  1240:     int h = XEiJ.regRn[0];
  1241:     if (h << 1 == 0 && XEiJ.regRn[1] == 0) {  //0のとき
  1242:       XEiJ.regRn[0] = 0;
  1243:       XEiJ.regRn[2] = 0;
  1244:     } else {  //0でないとき
  1245:       XEiJ.regRn[0] = (h & 0x800fffff) | 0x3ff00000;  //符号と仮数部を残して指数部を0にする
  1246:       XEiJ.regRn[2] = (h >>> 20 & 0x7ff) - 0x3ff;
  1247:     }
  1248:   }  //fpkDFREXP()
  1249: 
  1250:   //fpkDLDEXP ()
  1251:   //  $FE4A  __DLDEXP
  1252:   //  64bit浮動小数点数の合成
  1253:   //  <d0d1.d:64bit浮動小数点数。x
  1254:   //  <d2.l:xの指数部に加える値。y
  1255:   //  >d0d1.d:xの指数部にyを加えた値。x==0のときは0。エラーのときは変化しない
  1256:   //  >ccr:cs=指数部が範囲外
  1257:   public static void fpkDLDEXP () {
  1258:     int h = XEiJ.regRn[0];
  1259:     if (h << 1 == 0 && XEiJ.regRn[1] == 0) {  //0のとき
  1260:       XEiJ.regRn[0] = 0;
  1261:       XEiJ.regCCR = 0;
  1262:     } else {  //0でないとき
  1263:       int t = (h >>> 20 & 0x7ff) + XEiJ.regRn[2];
  1264:       if ((t & ~0x7ff) != 0) {  //指数部が範囲外
  1265:         XEiJ.regCCR = XEiJ.REG_CCR_C;
  1266:       } else {
  1267:         XEiJ.regRn[0] = (h & 0x800fffff) | t << 20;  //符号と仮数部を残して指数部を交換する
  1268:         XEiJ.regCCR = 0;
  1269:       }
  1270:     }
  1271:   }  //fpkDLDEXP()
  1272: 
  1273:   //fpkDADDONE ()
  1274:   //  $FE4B  __DADDONE
  1275:   //  64bit浮動小数点数に1を加える
  1276:   //  <d0d1.d:64bit浮動小数点数。x
  1277:   //  >d0d1.d:64bit浮動小数点数。x+1
  1278:   public static void fpkDADDONE () {
  1279:     //([int,int]→[long]→double)+1→[long]→[int,int]
  1280:     double xd = Double.longBitsToDouble ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1]);
  1281:     double zd = xd + 1.0;
  1282:     long l = Double.doubleToLongBits (zd);
  1283:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
  1284:       l = 0x7fffffffffffffffL;
  1285:     }
  1286:     XEiJ.regRn[0] = (int) (l >>> 32);
  1287:     XEiJ.regRn[1] = (int) l;
  1288:     XEiJ.regCCR = Double.isInfinite (zd) && !Double.isInfinite (xd) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C : 0;  //結果が±Infだが引数が±Infでないときはオーバーフロー
  1289:   }  //fpkDADDONE()
  1290: 
  1291:   //fpkDSUBONE ()
  1292:   //  $FE4C  __DSUBONE
  1293:   //  64bit浮動小数点数から1を引く
  1294:   //  <d0d1.d:64bit浮動小数点数。x
  1295:   //  >d0d1.d:64bit浮動小数点数。x-1
  1296:   public static void fpkDSUBONE () {
  1297:     //([int,int]→[long]→double)-1→[long]→[int,int]
  1298:     double xd = Double.longBitsToDouble ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1]);
  1299:     double zd = xd - 1.0;
  1300:     long l = Double.doubleToLongBits (zd);
  1301:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
  1302:       l = 0x7fffffffffffffffL;
  1303:     }
  1304:     XEiJ.regRn[0] = (int) (l >>> 32);
  1305:     XEiJ.regRn[1] = (int) l;
  1306:     XEiJ.regCCR = Double.isInfinite (zd) && !Double.isInfinite (xd) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C : 0;  //結果が±Infだが引数が±Infでないときはオーバーフロー
  1307:   }  //fpkDSUBONE()
  1308: 
  1309:   //fpkDDIVTWO ()
  1310:   //  $FE4D  __DDIVTWO
  1311:   //  64bit浮動小数点数を2で割る
  1312:   //  バグ
  1313:   //    FLOAT2.X 2.02/2.03は__DDIVTWO(0x0010000000000000L)がエラーになる
  1314:   //    FLOAT4.X 1.02は__DDIVTWO(0x0010000000000000L)がエラーになる
  1315:   //    FLOAT2.X 2.02/2.03は__DDIVTWO(0x000fffffffffffffL)がエラーになる
  1316:   //    FLOAT4.X 1.02は__DDIVTWO(0x000fffffffffffffL)がエラーになる
  1317:   //    FLOAT2.X 2.02/2.03は__DDIVTWO(0x0000000000000001L)が0x0000000000000001Lになる
  1318:   //    FLOAT4.X 1.02は__DDIVTWO(0x0000000000000001L)が0x0000000000000001Lになる
  1319:   //    FLOAT2.X 2.02/2.03は__DDIVTWO(-0)がエラーになる
  1320:   //    FLOAT4.X 1.02は__DDIVTWO(-0)がエラーになる
  1321:   //    FLOAT2.X 2.02/2.03は__DDIVTWO(0x8000000000000001L)がエラーになる
  1322:   //    FLOAT4.X 1.02は__DDIVTWO(0x8000000000000001L)がエラーになる
  1323:   //    FLOAT2.X 2.02/2.03は__DDIVTWO(0x800fffffffffffffL)がエラーになる
  1324:   //    FLOAT4.X 1.02は__DDIVTWO(0x800fffffffffffffL)がエラーになる
  1325:   //    FLOAT2.X 2.02/2.03は__DDIVTWO(0x8010000000000000L)がエラーになる
  1326:   //    FLOAT4.X 1.02は__DDIVTWO(0x8010000000000000L)がエラーになる
  1327:   //  <d0d1.d:64bit浮動小数点数。x
  1328:   //  >d0d1.d:64bit浮動小数点数。x/2
  1329:   //  >ccr:cs=アンダーフロー
  1330:   public static void fpkDDIVTWO () {
  1331:     //([int,int]→[long]→double)/2→[long]→[int,int]
  1332:     double xd = Double.longBitsToDouble ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1]);
  1333:     double zd = xd * 0.5;
  1334:     long l = Double.doubleToLongBits (zd);
  1335:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
  1336:       l = 0x7fffffffffffffffL;
  1337:     }
  1338:     XEiJ.regRn[0] = (int) (l >>> 32);
  1339:     XEiJ.regRn[1] = (int) l;
  1340:     XEiJ.regCCR = zd == 0.0 && xd != 0.0 ? XEiJ.REG_CCR_C : 0;  //結果が±0だが引数が±0でないときはアンダーフロー
  1341:   }  //fpkDDIVTWO()
  1342: 
  1343:   //fpkDIEECNV ()
  1344:   //  $FE4E  __DIEECNV
  1345:   //  64bit浮動小数点数をIEEEフォーマットに変換する(FLOAT1.X以外は何もしない)
  1346:   //  <d0d1.d:64bit浮動小数点数。x
  1347:   //  >d0d1.d:64bit浮動小数点数。x
  1348:   public static void fpkDIEECNV () {
  1349:   }  //fpkDIEECNV()
  1350: 
  1351:   //fpkIEEDCNV ()
  1352:   //  $FE4F  __IEEDCNV
  1353:   //  64bit浮動小数点数をIEEEフォーマットから変換する(FLOAT1.X以外は何もしない)
  1354:   //  <d0d1.d:64bit浮動小数点数。x
  1355:   //  >d0d1.d:64bit浮動小数点数。x
  1356:   public static void fpkIEEDCNV () {
  1357:   }  //fpkIEEDCNV()
  1358: 
  1359:   //fpkFTST ()
  1360:   //  $FE58  __FTST
  1361:   //  32bit浮動小数点数と0の比較
  1362:   //  x<=>0
  1363:   //  <d0.s:32bit浮動小数点数。x
  1364:   //  >ccr:lt=x<0,eq=x==0,gt=x>0
  1365:   public static void fpkFTST () {
  1366:     if (true) {
  1367:       int h = XEiJ.regRn[0];
  1368:       XEiJ.regCCR = h << 1 == 0 ? XEiJ.REG_CCR_Z : 0 <= h ? 0 : XEiJ.REG_CCR_N;  //NaNのときは0
  1369:     } else {
  1370:       //([int]→float)<=>0
  1371:       float f = Float.intBitsToFloat (XEiJ.regRn[0]);
  1372:       XEiJ.regCCR = f < 0.0F ? XEiJ.REG_CCR_N : f == 0.0F ? XEiJ.REG_CCR_Z : 0;  //NaNのときは0
  1373:     }
  1374:   }  //fpkFTST()
  1375: 
  1376:   //fpkFCMP ()
  1377:   //  $FE59  __FCMP
  1378:   //  32bit浮動小数点数の比較
  1379:   //  x<=>y
  1380:   //  <d0.s:32bit浮動小数点数。x
  1381:   //  <d1.s:32bit浮動小数点数。y
  1382:   //  >ccr:lt=x<y,eq=x==y,gt=x>y
  1383:   public static void fpkFCMP () {
  1384:     //([int]→float)<=>([int]→float)
  1385:     float xf = Float.intBitsToFloat (XEiJ.regRn[0]);
  1386:     float yf = Float.intBitsToFloat (XEiJ.regRn[1]);
  1387:     XEiJ.regCCR = xf < yf ? XEiJ.REG_CCR_N | XEiJ.REG_CCR_C : xf == yf ? XEiJ.REG_CCR_Z : 0;  //どちらかがNaNのときは0
  1388:   }  //fpkFCMP()
  1389: 
  1390:   //fpkFNEG ()
  1391:   //  $FE5A  __FNEG
  1392:   //  32bit浮動小数点数の符号反転
  1393:   //  <d0.s:32bit浮動小数点数。x
  1394:   //  >d0.s:32bit浮動小数点数。-x
  1395:   public static void fpkFNEG () {
  1396:     //-([int]→float)→[int]
  1397:     int h = Float.floatToIntBits (-Float.intBitsToFloat (XEiJ.regRn[0]));
  1398:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  1399:       h = 0x7fffffff;
  1400:     }
  1401:     XEiJ.regRn[0] = h;
  1402:   }  //fpkFNEG()
  1403: 
  1404:   //fpkFADD ()
  1405:   //  $FE5B  __FADD
  1406:   //  32bit浮動小数点数の加算
  1407:   //  <d0.s:32bit浮動小数点数。被加算数x
  1408:   //  <d1.s:32bit浮動小数点数。加算数y
  1409:   //  >d0.s:32bit浮動小数点数。和x+y
  1410:   //  >ccr:cs=エラー,vs=オーバーフロー
  1411:   public static void fpkFADD () {
  1412:     //([int]→float)+([int]→float)→[int]
  1413:     float xf = Float.intBitsToFloat (XEiJ.regRn[0]);
  1414:     float yf = Float.intBitsToFloat (XEiJ.regRn[1]);
  1415:     float zf = xf + yf;
  1416:     int h = Float.floatToIntBits (zf);
  1417:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  1418:       h = 0x7fffffff;
  1419:     }
  1420:     XEiJ.regRn[0] = h;
  1421:     XEiJ.regCCR = (Float.isNaN (xf) || Float.isNaN (yf) ? 0 :  //引数がNaN
  1422:            Float.isNaN (zf) ? XEiJ.REG_CCR_C :  //引数がNaNでないのに結果がNaNのときはエラー。(+Inf)+(-Inf)=NaN
  1423:            Float.isInfinite (xf) || Float.isInfinite (yf) ? 0 :  //引数が±Inf
  1424:            Float.isInfinite (zf) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C :  //引数が±Infでないのに結果が±Infのときはオーバーフロー
  1425:            0);
  1426:   }  //fpkFADD()
  1427: 
  1428:   //fpkFSUB ()
  1429:   //  $FE5C  __FSUB
  1430:   //  32bit浮動小数点数の減算
  1431:   //  <d0.s:32bit浮動小数点数。被減算数x
  1432:   //  <d1.s:32bit浮動小数点数。減算数y
  1433:   //  >d0.s:32bit浮動小数点数。差x-y
  1434:   //  >ccr:cs=エラー,vs=オーバーフロー
  1435:   public static void fpkFSUB () {
  1436:     //([int]→float)-([int]→float)→[int]
  1437:     float xf = Float.intBitsToFloat (XEiJ.regRn[0]);
  1438:     float yf = Float.intBitsToFloat (XEiJ.regRn[1]);
  1439:     float zf = xf - yf;
  1440:     int h = Float.floatToIntBits (zf);
  1441:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  1442:       h = 0x7fffffff;
  1443:     }
  1444:     XEiJ.regRn[0] = h;
  1445:     XEiJ.regCCR = (Float.isNaN (xf) || Float.isNaN (yf) ? 0 :  //引数がNaN
  1446:            Float.isNaN (zf) ? XEiJ.REG_CCR_C :  //引数がNaNでないのに結果がNaNのときはエラー。(+Inf)-(+Inf)=NaN
  1447:            Float.isInfinite (xf) || Float.isInfinite (yf) ? 0 :  //引数が±Inf
  1448:            Float.isInfinite (zf) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C :  //引数が±Infでないのに結果が±Infのときはオーバーフロー
  1449:            0);
  1450:   }  //fpkFSUB()
  1451: 
  1452:   //fpkFMUL ()
  1453:   //  $FE5D  __FMUL
  1454:   //  32bit浮動小数点数の乗算
  1455:   //  <d0.s:32bit浮動小数点数。被乗数x
  1456:   //  <d1.s:32bit浮動小数点数。乗数y
  1457:   //  >d0.s:32bit浮動小数点数。積x*y
  1458:   //  >ccr:cs=エラー,vs=オーバーフロー
  1459:   public static void fpkFMUL () {
  1460:     //([int]→float)*([int]→float)→[int]
  1461:     float xf = Float.intBitsToFloat (XEiJ.regRn[0]);
  1462:     float yf = Float.intBitsToFloat (XEiJ.regRn[1]);
  1463:     float zf = xf * yf;
  1464:     int h = Float.floatToIntBits (zf);
  1465:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  1466:       h = 0x7fffffff;
  1467:     }
  1468:     XEiJ.regRn[0] = h;
  1469:     XEiJ.regCCR = (Float.isNaN (xf) || Float.isNaN (yf) ? 0 :  //引数がNaN
  1470:            Float.isNaN (zf) ? XEiJ.REG_CCR_C :  //引数がNaNでないのに結果がNaNのときはエラー。(±0)*(±Inf)=NaN
  1471:            Float.isInfinite (xf) || Float.isInfinite (yf) ? 0 :  //引数が±Inf
  1472:            Float.isInfinite (zf) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C :  //引数が±Infでないのに結果が±Infのときはオーバーフロー
  1473:            0);
  1474:   }  //fpkFMUL()
  1475: 
  1476:   //fpkFDIV ()
  1477:   //  $FE5E  __FDIV
  1478:   //  32bit浮動小数点数の除算
  1479:   //  <d0.s:32bit浮動小数点数。被除数x
  1480:   //  <d1.s:32bit浮動小数点数。除数y
  1481:   //  >d0.s:32bit浮動小数点数。商x/y。ゼロ除算のときは不定
  1482:   //  >ccr:cs=エラー,eq=ゼロ除算,vs=オーバーフロー
  1483:   public static void fpkFDIV () {
  1484:     //([int]→float)/([int]→float)→[int]
  1485:     float xf = Float.intBitsToFloat (XEiJ.regRn[0]);
  1486:     float yf = Float.intBitsToFloat (XEiJ.regRn[1]);
  1487:     float zf = xf / yf;
  1488:     int h = Float.floatToIntBits (zf);
  1489:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  1490:       h = 0x7fffffff;
  1491:     }
  1492:     XEiJ.regRn[0] = h;
  1493:     XEiJ.regCCR = (Float.isNaN (xf) || Float.isNaN (yf) ? 0 :  //引数がNaN
  1494:            Float.isNaN (zf) ? XEiJ.REG_CCR_C :  //引数がNaNでないのに結果がNaNのときはエラー。(±0)/(±0)=NaN
  1495:            Float.isInfinite (xf) || Float.isInfinite (yf) ? 0 :  //引数が±Inf。(±Inf)/(±0)=(±Inf)
  1496:            yf == 0.0F ? XEiJ.REG_CCR_Z | XEiJ.REG_CCR_C :  //除数が±0のときはゼロ除算
  1497:            Float.isInfinite (zf) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C :  //引数が±Infでないのに結果が±Infのときはオーバーフロー
  1498:            0);
  1499:   }  //fpkFDIV()
  1500: 
  1501:   //fpkFMOD ()
  1502:   //  $FE5F  __FMOD
  1503:   //  32bit浮動小数点数の剰余算
  1504:   //  <d0.s:32bit浮動小数点数。被除数x
  1505:   //  <d1.s:32bit浮動小数点数。除数y
  1506:   //  >d0.s:32bit浮動小数点数。余りx%y。ゼロ除算のときは不定
  1507:   //  >ccr:cs=エラー,eq=ゼロ除算
  1508:   public static void fpkFMOD () {
  1509:     //([int]→float)%([int]→float)→[int]
  1510:     float xf = Float.intBitsToFloat (XEiJ.regRn[0]);
  1511:     float yf = Float.intBitsToFloat (XEiJ.regRn[1]);
  1512:     float zf = xf % yf;
  1513:     int h = Float.floatToIntBits (zf);
  1514:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  1515:       h = 0x7fffffff;
  1516:     }
  1517:     XEiJ.regRn[0] = h;
  1518:     XEiJ.regCCR = (Float.isNaN (xf) || Float.isNaN (yf) ? 0 :  //引数がNaN
  1519:            yf == 0.0F ? XEiJ.REG_CCR_Z | XEiJ.REG_CCR_C :  //除数が0のときはゼロ除算。(±Inf)%(±0)=NaN, x%(±0)=(±Inf)
  1520:            Float.isNaN (zf) ? XEiJ.REG_CCR_C :  //引数がNaNでないのに結果がNaNのときはエラー。(±Inf)%y=NaN
  1521:            Float.isInfinite (xf) || Float.isInfinite (yf) ? 0 :  //引数が±Inf
  1522:            Float.isInfinite (zf) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C :  //引数が±Infでないのに結果が±Infのときはオーバーフロー
  1523:            0);
  1524:   }  //fpkFMOD()
  1525: 
  1526:   //fpkFABS ()
  1527:   //  $FE60  __FABS
  1528:   //  32bit浮動小数点数の絶対値
  1529:   //  <d0.s:32bit浮動小数点数。x
  1530:   //  >d0.s:32bit浮動小数点数。abs(x)
  1531:   public static void fpkFABS () {
  1532:     //abs([int]→float)→[int]
  1533:     int h = Float.floatToIntBits (Math.abs (Float.intBitsToFloat (XEiJ.regRn[0])));
  1534:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  1535:       h = 0x7fffffff;
  1536:     }
  1537:     XEiJ.regRn[0] = h;
  1538:   }  //fpkFABS()
  1539: 
  1540:   //fpkFCEIL ()
  1541:   //  $FE61  __FCEIL
  1542:   //  32bit浮動小数点数の天井関数(引数を下回らない最小の整数)
  1543:   //  <d0.s:32bit浮動小数点数。x
  1544:   //  >d0.s:32bit浮動小数点数。ceil(x)
  1545:   public static void fpkFCEIL () {
  1546:     //ceil([int]→float→double)→float→[int]
  1547:     int h = Float.floatToIntBits ((float) Math.ceil ((double) Float.intBitsToFloat (XEiJ.regRn[0])));
  1548:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  1549:       h = 0x7fffffff;
  1550:     }
  1551:     XEiJ.regRn[0] = h;
  1552:   }  //fpkFCEIL()
  1553: 
  1554:   //fpkFFIX ()
  1555:   //  $FE62  __FFIX
  1556:   //  32bit浮動小数点数の切り落とし関数(絶対値について引数を上回らない最大の整数)
  1557:   //  <d0.s:32bit浮動小数点数。x
  1558:   //  >d0.s:32bit浮動小数点数。trunc(x)
  1559:   public static void fpkFFIX () {
  1560:     //trunc([int]→float→double)→float→[int]
  1561:     float f = Float.intBitsToFloat (XEiJ.regRn[0]);
  1562:     int h = Float.floatToIntBits (0.0 <= f ? (float) Math.floor ((double) f) : (float) Math.ceil ((double) f));  //0<=-0だがMath.floor(-0)=-0なので問題ない
  1563:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  1564:       h = 0x7fffffff;
  1565:     }
  1566:     XEiJ.regRn[0] = h;
  1567:   }  //fpkFFIX()
  1568: 
  1569:   //fpkFFLOOR ()
  1570:   //  $FE63  __FFLOOR
  1571:   //  32bit浮動小数点数の床関数(引数を上回らない最大の整数)
  1572:   //  <d0.s:32bit浮動小数点数。x
  1573:   //  >d0.s:32bit浮動小数点数。floor(x)
  1574:   public static void fpkFFLOOR () {
  1575:     //floor([int]→float→double)→float→[int]
  1576:     int h = Float.floatToIntBits ((float) Math.floor ((double) Float.intBitsToFloat (XEiJ.regRn[0])));
  1577:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  1578:       h = 0x7fffffff;
  1579:     }
  1580:     XEiJ.regRn[0] = h;
  1581:   }  //fpkFFLOOR()
  1582: 
  1583:   //fpkFFRAC ()
  1584:   //  $FE64  __FFRAC
  1585:   //  32bit浮動小数点数の幹小数部
  1586:   //  <d0.s:32bit浮動小数点数。x
  1587:   //  >d0.s:32bit浮動小数点数。frac(x)=copysign(x-trunc(x),x)
  1588:   public static void fpkFFRAC () {
  1589:     //frac([int]→float→double)→float→[int]
  1590:     int h = XEiJ.regRn[0];
  1591:     float f = Float.intBitsToFloat (h);
  1592:     h = (Float.isNaN (f) ? Float.floatToIntBits (Float.NaN) :  //frac(NaN)=NaN
  1593:          Float.isInfinite (f) ? h & 0x80000000 :  //frac(±Inf)=±0
  1594:          Float.floatToIntBits (0 <= h ? f - (float) Math.floor ((double) f) : -(-f - (float) Math.floor ((double) -f))));  //0<=-0なので0<=f?~は不可
  1595:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  1596:       h = 0x7fffffff;
  1597:     }
  1598:     XEiJ.regRn[0] = h;
  1599:   }  //fpkFFRAC()
  1600: 
  1601:   //fpkFSGN ()
  1602:   //  $FE65  __FSGN
  1603:   //  32bit浮動小数点数の符号
  1604:   //  <d0.s:32bit浮動小数点数。x
  1605:   //  >d0.s:32bit浮動小数点数。signum(x)
  1606:   public static void fpkFSGN () {
  1607:     //signum([int]→float)→[int]
  1608:     int h = Float.floatToIntBits (Math.signum (Float.intBitsToFloat (XEiJ.regRn[0])));  //Math.signum(-0)は-0
  1609:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  1610:       h = 0x7fffffff;
  1611:     }
  1612:     XEiJ.regRn[0] = h;
  1613:   }  //fpkFSGN()
  1614: 
  1615:   //fpkFSIN ()
  1616:   //  $FE66  __FSIN
  1617:   //  32bit浮動小数点数の正弦
  1618:   //  <d0.s:32bit浮動小数点数。x
  1619:   //  >d0.s:32bit浮動小数点数。sin(x)
  1620:   //  >ccr:x=±Inf。C以外は不定
  1621:   public static void fpkFSIN () {
  1622:     //sin([int]→float→double)→float→[int]
  1623:     float xf = Float.intBitsToFloat (XEiJ.regRn[0]);
  1624:     float zf = (float) Math.sin ((double) xf);
  1625:     int h = Float.floatToIntBits (zf);
  1626:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  1627:       h = 0x7fffffff;
  1628:     }
  1629:     XEiJ.regRn[0] = h;
  1630:     XEiJ.regCCR = !Float.isNaN (xf) && Float.isNaN (zf) ? XEiJ.REG_CCR_C : 0;  //引数がNaNでないのに結果がNaNのときはエラー。sin(±Inf)=NaN
  1631:   }  //fpkFSIN()
  1632: 
  1633:   //fpkFCOS ()
  1634:   //  $FE67  __FCOS
  1635:   //  32bit浮動小数点数の余弦
  1636:   //  <d0.s:32bit浮動小数点数。x
  1637:   //  >d0.s:32bit浮動小数点数。cos(x)
  1638:   //  >ccr:x=±Inf。C以外は不定
  1639:   public static void fpkFCOS () {
  1640:     //cos([int]→float→double)→float→[int]
  1641:     float xf = Float.intBitsToFloat (XEiJ.regRn[0]);
  1642:     float zf = (float) Math.cos ((double) xf);
  1643:     int h = Float.floatToIntBits (zf);
  1644:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  1645:       h = 0x7fffffff;
  1646:     }
  1647:     XEiJ.regRn[0] = h;
  1648:     XEiJ.regCCR = !Float.isNaN (xf) && Float.isNaN (zf) ? XEiJ.REG_CCR_C : 0;  //引数がNaNでないのに結果がNaNのときはエラー。cos(±Inf)=NaN
  1649:   }  //fpkFCOS()
  1650: 
  1651:   //fpkFTAN ()
  1652:   //  $FE68  __FTAN
  1653:   //  32bit浮動小数点数の正接
  1654:   //  <d0.s:32bit浮動小数点数。x
  1655:   //  >d0.s:32bit浮動小数点数。tan(x)
  1656:   //  >ccr:x=±Inf。C以外は不定
  1657:   public static void fpkFTAN () {
  1658:     //tan([int]→float→double)→float→[int]
  1659:     float xf = Float.intBitsToFloat (XEiJ.regRn[0]);
  1660:     float zf = (float) Math.tan ((double) xf);
  1661:     int h = Float.floatToIntBits (zf);
  1662:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  1663:       h = 0x7fffffff;
  1664:     }
  1665:     XEiJ.regRn[0] = h;
  1666:     XEiJ.regCCR = !Float.isNaN (xf) && Float.isNaN (zf) ? XEiJ.REG_CCR_C : 0;  //引数がNaNでないのに結果がNaNのときはエラー。tan(±Inf)=NaN
  1667:   }  //fpkFTAN()
  1668: 
  1669:   //fpkFATAN ()
  1670:   //  $FE69  __FATAN
  1671:   //  32bit浮動小数点数の逆正接
  1672:   //  <d0.s:32bit浮動小数点数。x
  1673:   //  >d0.s:32bit浮動小数点数。atan(x)
  1674:   public static void fpkFATAN () {
  1675:     //atan([int]→float→double)→float→[int]
  1676:     int h = Float.floatToIntBits ((float) Math.atan ((double) Float.intBitsToFloat (XEiJ.regRn[0])));
  1677:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  1678:       h = 0x7fffffff;
  1679:     }
  1680:     XEiJ.regRn[0] = h;
  1681:   }  //fpkFATAN()
  1682: 
  1683:   //fpkFLOG ()
  1684:   //  $FE6A  __FLOG
  1685:   //  32bit浮動小数点数の自然対数
  1686:   //  <d0.s:32bit浮動小数点数。x
  1687:   //  >d0.s:32bit浮動小数点数。log(x)
  1688:   //  >ccr:0=エラーなし,C=x<0,Z|C=x==0
  1689:   public static void fpkFLOG () {
  1690:     //log([int]→float→double)→float→[int]
  1691:     float xf = Float.intBitsToFloat (XEiJ.regRn[0]);
  1692:     float zf = (float) Math.log ((double) xf);
  1693:     int h = Float.floatToIntBits (zf);
  1694:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  1695:       h = 0x7fffffff;
  1696:     }
  1697:     XEiJ.regRn[0] = h;
  1698:     XEiJ.regCCR = (Float.isNaN (xf) ? 0 :  //引数がNaN
  1699:            Float.isNaN (zf) ? XEiJ.REG_CCR_C :  //引数がNaNでないのに結果がNaNのときはエラー。log(-x)=NaN
  1700:            Float.isInfinite (xf) ? 0 :  //引数が±Inf
  1701:            Float.isNaN (zf) ? XEiJ.REG_CCR_Z | XEiJ.REG_CCR_C :  //引数が±Infでないのに結果が±Infのときはエラー。log(±0)=-Inf
  1702:            0);
  1703:   }  //fpkFLOG()
  1704: 
  1705:   //fpkFEXP ()
  1706:   //  $FE6B  __FEXP
  1707:   //  32bit浮動小数点数の指数関数
  1708:   //  <d0.s:32bit浮動小数点数。x
  1709:   //  >d0.s:32bit浮動小数点数。exp(x)
  1710:   //  >ccr:cs=オーバーフロー
  1711:   public static void fpkFEXP () {
  1712:     //exp([int]→float→double)→float→[int]
  1713:     int xh = XEiJ.regRn[0];
  1714:     int zh = Float.floatToIntBits ((float) Math.exp ((double) Float.intBitsToFloat (xh)));
  1715:     if (FPK_FPCP_NAN && zh == 0x7fc00000) {
  1716:       zh = 0x7fffffff;
  1717:     }
  1718:     XEiJ.regRn[0] = zh;
  1719:     XEiJ.regCCR = (zh & 0x7fc00000) == 0x7fc00000 && (xh & 0x7fc00000) != 0x7fc00000 ? XEiJ.REG_CCR_C : 0;  //結果が±Inf,NaNだが引数が±Inf,NaNでなかったときはエラー
  1720:   }  //fpkFEXP()
  1721: 
  1722:   //fpkFSQR ()
  1723:   //  $FE6C  __FSQR
  1724:   //  32bit浮動小数点数の平方根
  1725:   //  <d0.s:32bit浮動小数点数。x
  1726:   //  >d0.s:32bit浮動小数点数。sqrt(x)
  1727:   //  >ccr:cs=x<0
  1728:   public static void fpkFSQR () {
  1729:     //sqrt([int]→float→double)→float→[int]
  1730:     float xf = Float.intBitsToFloat (XEiJ.regRn[0]);
  1731:     int h = Float.floatToIntBits ((float) Math.sqrt ((double) xf));
  1732:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  1733:       h = 0x7fffffff;
  1734:     }
  1735:     XEiJ.regRn[0] = h;
  1736:     XEiJ.regCCR = xf < 0.0F ? XEiJ.REG_CCR_C : 0;  //NaNはエラーなし
  1737:   }  //fpkFSQR()
  1738: 
  1739:   //fpkFPI ()
  1740:   //  $FE6D  __FPI
  1741:   //  32bit浮動小数点数の円周率
  1742:   //  >d0.s:32bit浮動小数点数。pi
  1743:   public static void fpkFPI () {
  1744:     //pi→float→[int]
  1745:     if (true) {
  1746:       XEiJ.regRn[0] = 0x40490fdb;
  1747:     } else {
  1748:       XEiJ.regRn[0] = Float.floatToIntBits ((float) Math.PI);
  1749:     }
  1750:   }  //fpkFPI()
  1751: 
  1752:   //fpkFNPI ()
  1753:   //  $FE6E  __FNPI
  1754:   //  32bit浮動小数点数の円周率倍
  1755:   //  <d0.s:32bit浮動小数点数。x
  1756:   //  >d0.s:32bit浮動小数点数。x*pi
  1757:   //  >ccr:cs=オーバーフロー
  1758:   public static void fpkFNPI () {
  1759:     //([int]→float→double)*pi→float→[int]
  1760:     int xh = XEiJ.regRn[0];
  1761:     //  倍精度のπを倍精度で掛けて単精度に丸める
  1762:     int zh = Float.floatToIntBits ((float) ((double) Float.intBitsToFloat (xh) * Math.PI));
  1763:     if (FPK_FPCP_NAN && zh == 0x7fc00000) {
  1764:       zh = 0x7fffffff;
  1765:     }
  1766:     XEiJ.regRn[0] = zh;
  1767:     XEiJ.regCCR = (zh & 0x7fc00000) == 0x7fc00000 && (xh & 0x7fc00000) != 0x7fc00000 ? XEiJ.REG_CCR_C : 0;  //結果が±Inf,NaNだが引数が±Inf,NaNでなかったときはエラー
  1768:   }  //fpkFNPI()
  1769: 
  1770:   //fpkFPOWER ()
  1771:   //  $FE6F  __FPOWER
  1772:   //  32bit浮動小数点数の累乗
  1773:   //  <d0.s:32bit浮動小数点数。x
  1774:   //  <d1.s:32bit浮動小数点数。y
  1775:   //  >d0.s:32bit浮動小数点数。pow(x,y)
  1776:   //  >ccr:cs=オーバーフロー
  1777:   public static void fpkFPOWER () {
  1778:     //pow([int]→float→double,[int]→float→double)→float→[int]
  1779:     float xf = Float.intBitsToFloat (XEiJ.regRn[0]);
  1780:     float yf = Float.intBitsToFloat (XEiJ.regRn[1]);
  1781:     float zf = (float) Math.pow ((double) xf, (double) yf);
  1782:     int zh = Float.floatToIntBits (zf);
  1783:     if (FPK_FPCP_NAN && zh == 0x7fc00000) {
  1784:       zh = 0x7fffffff;
  1785:     }
  1786:     XEiJ.regRn[0] = zh;
  1787:     XEiJ.regCCR = (Float.isNaN (xf) || Float.isNaN (yf) ? 0 :  //引数がNaN
  1788:            Float.isNaN (zf) ? XEiJ.REG_CCR_C :  //引数がNaNでないのに結果がNaNのときはエラー
  1789:            Float.isInfinite (xf) || Float.isInfinite (yf) ? 0 :  //引数が±Inf
  1790:            Float.isNaN (zf) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C :  //引数が±Infでないのに結果が±Infのときはオーバーフロー
  1791:            0);
  1792:   }  //fpkFPOWER()
  1793: 
  1794:   //fpkFRND ()
  1795:   //  $FE70  __FRND
  1796:   //  32bit浮動小数点数の乱数
  1797:   //  >d0.s:32bit浮動小数点数。rnd()。0以上1未満
  1798:   public static void fpkFRND () {
  1799:     //FRND()=DTOF(RND())
  1800:     long l = 0xffffffffL & fpkRndLong ();  //下位
  1801:     l |= (0x001fffffL & fpkRndLong ()) << 32;  //上位。順序に注意
  1802:     //  ここでl==0LのときLong.numberOfLeadingZeros(z)==64なので乱数の値は2^-54になる
  1803:     //  FLOATn.Xはその場合を考慮しておらず0のときも先頭の1のビットを探し続けて無限ループに陥ると思われる
  1804:     //  実際に0が53ビット並ぶことはないかも知れない
  1805:     int o = Long.numberOfLeadingZeros (l) - 11;
  1806:     l = ((long) (1022 - 1 - o) << 52) + (l << o);  //指数部を1減らしておいてbit52に移動した仮数部の先頭の1を加えている
  1807:     XEiJ.regRn[0] = Float.floatToIntBits ((float) Double.longBitsToDouble (l));
  1808:   }  //fpkFRND()
  1809: 
  1810:   //fpkFSINH ()
  1811:   //  $FE71  __FSINH
  1812:   //  32bit浮動小数点数の双曲線正弦
  1813:   //  <d0.s:32bit浮動小数点数。x
  1814:   //  >d0.s:32bit浮動小数点数。sinh(x)
  1815:   //  >ccr:cs=エラー,vs=オーバーフロー
  1816:   public static void fpkFSINH () {
  1817:     //sinh([int]→float→double)→float→[int]
  1818:     float xf = Float.intBitsToFloat (XEiJ.regRn[0]);
  1819:     float zf = (float) Math.sinh ((double) xf);
  1820:     int zh = Float.floatToIntBits (zf);
  1821:     if (FPK_FPCP_NAN && zh == 0x7fc00000) {
  1822:       zh = 0x7fffffff;
  1823:     }
  1824:     XEiJ.regRn[0] = zh;
  1825:     XEiJ.regCCR = (Float.isNaN (xf) ? 0 :  //引数がNaN
  1826:            Float.isNaN (zf) ? XEiJ.REG_CCR_C :  //引数がNaNでないのに結果がNaNのときはエラー
  1827:            Float.isInfinite (xf) ? 0 :  //引数が±Inf
  1828:            Float.isNaN (zf) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C :  //引数が±Infでないのに結果が±Infのときはオーバーフロー
  1829:            0);
  1830:   }  //fpkFSINH()
  1831: 
  1832:   //fpkFCOSH ()
  1833:   //  $FE72  __FCOSH
  1834:   //  32bit浮動小数点数の双曲線余弦
  1835:   //  <d0.s:32bit浮動小数点数。x
  1836:   //  >d0.s:32bit浮動小数点数。cosh(x)
  1837:   //  >ccr:cs=エラー,vs=オーバーフロー
  1838:   public static void fpkFCOSH () {
  1839:     //cosh([int]→float→double)→float→[int]
  1840:     float xf = Float.intBitsToFloat (XEiJ.regRn[0]);
  1841:     float zf = (float) Math.cosh ((double) xf);
  1842:     int zh = Float.floatToIntBits (zf);
  1843:     if (FPK_FPCP_NAN && zh == 0x7fc00000) {
  1844:       zh = 0x7fffffff;
  1845:     }
  1846:     XEiJ.regRn[0] = zh;
  1847:     XEiJ.regCCR = (Float.isNaN (xf) ? 0 :  //引数がNaN
  1848:            Float.isNaN (zf) ? XEiJ.REG_CCR_C :  //引数がNaNでないのに結果がNaNのときはエラー
  1849:            Float.isInfinite (xf) ? 0 :  //引数が±Inf
  1850:            Float.isNaN (zf) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C :  //引数が±Infでないのに結果が±Infのときはオーバーフロー
  1851:            0);
  1852:   }  //fpkFCOSH()
  1853: 
  1854:   //fpkFTANH ()
  1855:   //  $FE73  __FTANH
  1856:   //  32bit浮動小数点数の双曲線正接
  1857:   //  <d0.s:32bit浮動小数点数。x
  1858:   //  >d0.s:32bit浮動小数点数。tanh(x)
  1859:   public static void fpkFTANH () {
  1860:     //tanh([int]→float→double)→float→[int]
  1861:     int h = Float.floatToIntBits ((float) Math.tanh ((double) Float.intBitsToFloat (XEiJ.regRn[0])));
  1862:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  1863:       h = 0x7fffffff;
  1864:     }
  1865:     XEiJ.regRn[0] = h;
  1866:   }  //fpkFTANH()
  1867: 
  1868:   //fpkFATANH ()
  1869:   //  $FE74  __FATANH
  1870:   //  32bit浮動小数点数の逆双曲線正接
  1871:   //  <d0.s:32bit浮動小数点数。x
  1872:   //  >d0.s:32bit浮動小数点数。atanh(x)
  1873:   //  >ccr:cs=x<=-1||1<=x
  1874:   public static void fpkFATANH () {
  1875:     //atanh([int]→float→double)→float→[int]
  1876:     double d = (double) Float.intBitsToFloat (XEiJ.regRn[0]);
  1877:     double s = Math.signum (d);
  1878:     double a = Math.abs (d);
  1879:     if (a < 1.0) {
  1880:       d = s * (Math.log1p (a) - Math.log1p (-a)) * 0.5;  //Math.atanh(double)がない
  1881:       XEiJ.regCCR = 0;
  1882:     } else if (a == 1.0) {
  1883:       d = s * Double.POSITIVE_INFINITY;
  1884:       XEiJ.regCCR = XEiJ.REG_CCR_C;
  1885:     } else {
  1886:       d = Double.NaN;
  1887:       XEiJ.regCCR = XEiJ.REG_CCR_C;
  1888:     }
  1889:     int h = Float.floatToIntBits ((float) d);
  1890:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  1891:       h = 0x7fffffff;
  1892:     }
  1893:     XEiJ.regRn[0] = h;
  1894:   }  //fpkFATANH()
  1895: 
  1896:   //fpkFASIN ()
  1897:   //  $FE75  __FASIN
  1898:   //  32bit浮動小数点数の逆正弦
  1899:   //  <d0.s:32bit浮動小数点数。x
  1900:   //  >d0.s:32bit浮動小数点数。asin(x)
  1901:   //  >ccr:cs=x<-1||1<x
  1902:   public static void fpkFASIN () {
  1903:     //asin([int]→float→double)→float→[int]
  1904:     double d = (double) Float.intBitsToFloat (XEiJ.regRn[0]);
  1905:     if (d < -1.0 || 1.0 < d) {  //定義域の外。±1,NaNを含まない
  1906:       d = Double.NaN;
  1907:       XEiJ.regCCR = XEiJ.REG_CCR_C;
  1908:     } else {  //定義域の中。±1,NaNを含む
  1909:       d = Math.asin (d);
  1910:       XEiJ.regCCR = 0;
  1911:     }
  1912:     int h = Float.floatToIntBits ((float) d);
  1913:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  1914:       h = 0x7fffffff;
  1915:     }
  1916:     XEiJ.regRn[0] = h;
  1917:   }  //fpkFASIN()
  1918: 
  1919:   //fpkFACOS ()
  1920:   //  $FE76  __FACOS
  1921:   //  32bit浮動小数点数の逆余弦
  1922:   //  <d0.s:32bit浮動小数点数。x
  1923:   //  >d0.s:32bit浮動小数点数。acos(x)
  1924:   //  >ccr:cs=x<-1||1<x
  1925:   public static void fpkFACOS () {
  1926:     //acos([int]→float→double)→float→[int]
  1927:     double d = (double) Float.intBitsToFloat (XEiJ.regRn[0]);
  1928:     if (d < -1.0 || 1.0 < d) {  //定義域の外。±1,NaNを含まない
  1929:       d = Double.NaN;
  1930:       XEiJ.regCCR = XEiJ.REG_CCR_C;
  1931:     } else {  //定義域の中。±1,NaNを含む
  1932:       d = Math.acos (d);
  1933:       XEiJ.regCCR = 0;
  1934:     }
  1935:     int h = Float.floatToIntBits ((float) d);
  1936:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  1937:       h = 0x7fffffff;
  1938:     }
  1939:     XEiJ.regRn[0] = h;
  1940:   }  //fpkFACOS()
  1941: 
  1942:   //fpkFLOG10 ()
  1943:   //  $FE77  __FLOG10
  1944:   //  32bit浮動小数点数の常用対数
  1945:   //  <d0.s:32bit浮動小数点数。x
  1946:   //  >d0.s:32bit浮動小数点数。log10(x)
  1947:   //  >ccr:0=エラーなし,C=x<0,Z|C=x==0
  1948:   public static void fpkFLOG10 () {
  1949:     //log10([int]→float→double)→float→[int]
  1950:     double xd = (double) Float.intBitsToFloat (XEiJ.regRn[0]);
  1951:     double zd = Math.log10 (xd);
  1952:     int h = Float.floatToIntBits ((float) zd);
  1953:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  1954:       h = 0x7fffffff;
  1955:     }
  1956:     XEiJ.regRn[0] = h;
  1957:     XEiJ.regCCR = (Double.isNaN (xd) ? 0 :  //引数がNaN
  1958:            Double.isNaN (zd) ? XEiJ.REG_CCR_C :  //引数がNaNでないのに結果がNaNのときはエラー。log10(-x)=NaN
  1959:            Double.isInfinite (xd) ? 0 :  //引数が±Inf
  1960:            Double.isInfinite (zd) ? XEiJ.REG_CCR_Z | XEiJ.REG_CCR_C :  //引数が±Infでないのに結果が±Infのときはエラー。log10(±0)=-Inf
  1961:            0);
  1962:   }  //fpkFLOG10()
  1963: 
  1964:   //fpkFLOG2 ()
  1965:   //  $FE78  __FLOG2
  1966:   //  32bit浮動小数点数の二進対数
  1967:   //  <d0.s:32bit浮動小数点数。x
  1968:   //  >d0.s:32bit浮動小数点数。log2(x)
  1969:   //  >ccr:0=エラーなし,C=x<0,Z|C=x==0
  1970:   public static void fpkFLOG2 () {
  1971:     //log2([int]→float→double)→float→[int]
  1972:     double xd = (double) Float.intBitsToFloat (XEiJ.regRn[0]);
  1973:     double zd = Math.log (xd) / 0.69314718055994530941723212146;  //log(2)。Math.log2(double)がない
  1974:     int h = Float.floatToIntBits ((float) zd);
  1975:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  1976:       h = 0x7fffffff;
  1977:     }
  1978:     XEiJ.regRn[0] = h;
  1979:     XEiJ.regCCR = (Double.isNaN (xd) ? 0 :  //引数がNaN
  1980:            Double.isNaN (zd) ? XEiJ.REG_CCR_C :  //引数がNaNでないのに結果がNaNのときはエラー。log2(-x)=NaN
  1981:            Double.isInfinite (xd) ? 0 :  //引数が±Inf
  1982:            Double.isInfinite (zd) ? XEiJ.REG_CCR_Z | XEiJ.REG_CCR_C :  //引数が±Infでないのに結果が±Infのときはエラー。log2(±0)=-Inf
  1983:            0);
  1984:   }  //fpkFLOG2()
  1985: 
  1986:   //fpkFFREXP ()
  1987:   //  $FE79  __FFREXP
  1988:   //  32bit浮動小数点数の分解
  1989:   //  <d0.s:32bit浮動小数点数。x
  1990:   //  >d0.s:xの指数部を0にした値。x==0のときは0
  1991:   //  >d1.l:xの指数部。x==0のときは0
  1992:   public static void fpkFFREXP () {
  1993:     int h = XEiJ.regRn[0];
  1994:     if (h << 1 == 0) {  //0のとき
  1995:       XEiJ.regRn[0] = 0;
  1996:       XEiJ.regRn[1] = 0;
  1997:     } else {  //0でないとき
  1998:       XEiJ.regRn[0] = (h & 0x807fffff) | 0x3f800000;  //符号と仮数部を残して指数部を0にする
  1999:       XEiJ.regRn[1] = (h >>> 23 & 255) - 0x7f;
  2000:     }
  2001:   }  //fpkFFREXP()
  2002: 
  2003:   //fpkFLDEXP ()
  2004:   //  $FE7A  __FLDEXP
  2005:   //  32bit浮動小数点数の合成
  2006:   //  <d0.s:32bit浮動小数点数。x
  2007:   //  <d1.l:xの指数部に加える値。y
  2008:   //  >d0.s:xの指数部にyを加えた値。x==0のときは0。エラーのときは変化しない
  2009:   //  >ccr:0=エラーなし,C=指数部が範囲外
  2010:   public static void fpkFLDEXP () {
  2011:     int h = XEiJ.regRn[0];
  2012:     if (h << 1 == 0) {  //0のとき
  2013:       XEiJ.regRn[0] = 0;
  2014:       XEiJ.regCCR = 0;
  2015:     } else {  //0でないとき
  2016:       int t = (h >>> 23 & 255) + XEiJ.regRn[2];
  2017:       if ((t & ~0xff) != 0) {  //指数部が範囲外
  2018:         XEiJ.regCCR = XEiJ.REG_CCR_C;
  2019:       } else {
  2020:         XEiJ.regRn[0] = (h & 0x807fffff) | t << 23;  //符号と仮数部を残して指数部を交換する
  2021:         XEiJ.regCCR = 0;
  2022:       }
  2023:     }
  2024:   }  //fpkFLDEXP()
  2025: 
  2026:   //fpkFADDONE ()
  2027:   //  $FE7B  __FADDONE
  2028:   //  32bit浮動小数点数に1を加える
  2029:   //  <d0.s:32bit浮動小数点数。x
  2030:   //  >d0.s:32bit浮動小数点数。x+1
  2031:   public static void fpkFADDONE () {
  2032:     //([int]→float)+1→[int]
  2033:     float xf = Float.intBitsToFloat (XEiJ.regRn[0]);
  2034:     float zf = xf + 1.0F;
  2035:     int h = Float.floatToIntBits (zf);
  2036:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  2037:       h = 0x7fffffff;
  2038:     }
  2039:     XEiJ.regRn[0] = h;
  2040:     XEiJ.regCCR = Double.isInfinite (zf) && !Float.isInfinite (xf) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C : 0;  //結果が±Infだが引数が±Infでないときはオーバーフロー
  2041:   }  //fpkFADDONE()
  2042: 
  2043:   //fpkFSUBONE ()
  2044:   //  $FE7C  __FSUBONE
  2045:   //  32bit浮動小数点数から1を引く
  2046:   //  <d0.s:32bit浮動小数点数。x
  2047:   //  >d0.s:32bit浮動小数点数。x-1
  2048:   public static void fpkFSUBONE () {
  2049:     //([int]→float)-1→[int]
  2050:     float xf = Float.intBitsToFloat (XEiJ.regRn[0]);
  2051:     float zf = xf - 1.0F;
  2052:     int h = Float.floatToIntBits (zf);
  2053:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  2054:       h = 0x7fffffff;
  2055:     }
  2056:     XEiJ.regRn[0] = h;
  2057:     XEiJ.regCCR = Double.isInfinite (zf) && !Float.isInfinite (xf) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C : 0;  //結果が±Infだが引数が±Infでないときはオーバーフロー
  2058:   }  //fpkFSUBONE()
  2059: 
  2060:   //fpkFDIVTWO ()
  2061:   //  $FE7D  __FDIVTWO
  2062:   //  32bit浮動小数点数を2で割る
  2063:   //  <d0.s:32bit浮動小数点数。x
  2064:   //  >d0.s:32bit浮動小数点数。x/2
  2065:   //  >ccr:0=エラーなし,C=アンダーフロー
  2066:   public static void fpkFDIVTWO () {
  2067:     //([int]→float)/2→[int]
  2068:     float xf = Float.intBitsToFloat (XEiJ.regRn[0]);
  2069:     float zf = xf * 0.5F;
  2070:     int h = Float.floatToIntBits (zf);
  2071:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  2072:       h = 0x7fffffff;
  2073:     }
  2074:     XEiJ.regRn[0] = h;
  2075:     XEiJ.regCCR = zf == 0.0F && xf != 0.0F ? XEiJ.REG_CCR_C : 0;  //結果が±0だが引数が±0でないときはアンダーフロー
  2076:   }  //fpkFDIVTWO()
  2077: 
  2078:   //fpkFIEECNV ()
  2079:   //  $FE7E  __FIEECNV
  2080:   //  32bit浮動小数点数をIEEEフォーマットに変換する(FLOAT1.X以外は何もしない)
  2081:   //  <d0.s:32bit浮動小数点数。x
  2082:   //  >d0.s:32bit浮動小数点数。x
  2083:   public static void fpkFIEECNV () {
  2084:   }  //fpkFIEECNV()
  2085: 
  2086:   //fpkIEEFCNV ()
  2087:   //  $FE7F  __IEEFCNV
  2088:   //  32bit浮動小数点数をIEEEフォーマットから変換する(FLOAT1.X以外は何もしない)
  2089:   //  <d0.s:32bit浮動小数点数。x
  2090:   //  >d0.s:32bit浮動小数点数。x
  2091:   public static void fpkIEEFCNV () {
  2092:   }  //fpkIEEFCNV()
  2093: 
  2094:   //fpkFEVARG ()
  2095:   //  $FEFE  __FEVARG
  2096:   //  バージョン確認
  2097:   //  >d0.l:'HS86'($48533836)=FLOAT1.X,'IEEE'($49454545)=FLOAT2.X/FLOAT3.X/FLOAT4.X
  2098:   //  >d1.l:'SOFT'($534F4654)=FLOAT1.X/FLOAT2.X,'FPCP'($46504350)=FLOAT3.X,'FP20'($46503230)=FLOAT4.X
  2099:   public static void fpkFEVARG () {
  2100:     XEiJ.regRn[0] = 'I' << 24 | 'E' << 16 | 'E' << 8 | 'E';
  2101:     XEiJ.regRn[1] = 'X' << 24 | 'E' << 16 | 'i' << 8 | 'J';
  2102:   }  //fpkFEVARG()
  2103: 
  2104:   //fpkFEVECS ()
  2105:   //  $FEFF  __FEVECS
  2106:   //  ベクタ設定
  2107:   //  メモ
  2108:   //    FLOATn.Xに処理させる
  2109:   //    登録してもFEファンクション命令をOFFにしなければ既存のFEファンクション命令に上書きすることはできない
  2110:   //  <d0.l:FEファンクションコール番号。$FE00~$FEFF
  2111:   //  <a0.l:新アドレス
  2112:   //  >d0.l:旧アドレス。-1=エラー
  2113:   public static void fpkFEVECS () {
  2114:     XEiJ.regRn[0] = -1;
  2115:   }  //fpkFEVECS()
  2116: 
  2117: 
  2118: 
  2119:   //fpkSTOL ()
  2120:   //  $FE10  __STOL
  2121:   //  10進数の文字列を32bit符号あり整数に変換する
  2122:   //  /^[ \t]*[-+]?[0-9]+/
  2123:   //  先頭の'\t'と' 'を読み飛ばす
  2124:   //  <a0.l:10進数の文字列の先頭
  2125:   //  >d0.l:32bit符号あり整数
  2126:   //  >a0.l:10進数の文字列の直後('\0'とは限らない)
  2127:   //  >ccr:0=エラーなし,N|C=文法エラー,V|C=オーバーフロー
  2128:   public static void fpkSTOL () throws M68kException {
  2129:     int a = XEiJ.regRn[8];  //a0
  2130:     int c = XEiJ.busRbz (a);
  2131:     while (c == ' ' || c == '\t') {
  2132:       c = XEiJ.busRbz (++a);
  2133:     }
  2134:     int n = '7';  //'7'=正,'8'=負
  2135:     if (c == '-') {  //負
  2136:       n = '8';
  2137:       c = XEiJ.busRbz (++a);
  2138:     } else if (c == '+') {  //正
  2139:       c = XEiJ.busRbz (++a);
  2140:     }
  2141:     if (!('0' <= c && c <= '9')) {  //数字が1つもない
  2142:       XEiJ.regRn[8] = a;  //a0
  2143:       XEiJ.regCCR = XEiJ.REG_CCR_N | XEiJ.REG_CCR_C;
  2144:       return;
  2145:     }
  2146:     int x = c - '0';  //値
  2147:     for (c = XEiJ.busRbz (++a); '0' <= c && c <= '9'; c = XEiJ.busRbz (++a)) {
  2148:       if (214748364 < x || x == 214748364 && n < c) {  //正のとき2147483647、負のとき2147483648より大きくなるときオーバーフロー
  2149:         XEiJ.regRn[8] = a;  //a0
  2150:         XEiJ.regCCR = XEiJ.REG_CCR_V | XEiJ.REG_CCR_C;
  2151:         return;
  2152:       }
  2153:       x = x * 10 + (c - '0');
  2154:     }
  2155:     if (n != '7') {  //負
  2156:       x = -x;
  2157:     }
  2158:     XEiJ.regRn[0] = x;  //d0
  2159:     XEiJ.regRn[8] = a;  //a0
  2160:     XEiJ.regCCR = 0;
  2161:   }  //fpkSTOL()
  2162: 
  2163:   //fpkLTOS ()
  2164:   //  $FE11  __LTOS
  2165:   //  32bit符号あり整数を10進数の文字列に変換する
  2166:   //  /^-?[1-9][0-9]*$/
  2167:   //  <d0.l:32bit符号あり整数
  2168:   //  <a0.l:文字列バッファの先頭
  2169:   //  >a0.l:10進数の文字列の直後('\0'の位置)
  2170:   public static void fpkLTOS () throws M68kException {
  2171:     int x = XEiJ.regRn[0];  //d0
  2172:     int a = XEiJ.regRn[8];  //a0
  2173:     if (x < 0) {  //負
  2174:       XEiJ.busWb (a++, '-');
  2175:       x = -x;
  2176:     }
  2177:     long t = XEiJ.fmtBcd12 (0xffffffffL & x);  //符号は取り除いてあるがx=0x80000000の場合があるので(long)xは不可
  2178:     XEiJ.regRn[8] = a += Math.max (1, 67 - Long.numberOfLeadingZeros (t) >> 2);  //a0
  2179:     XEiJ.busWb (a, 0);
  2180:     do {
  2181:       XEiJ.busWb (--a, '0' | (int) t & 15);
  2182:     } while ((t >>>= 4) != 0L);
  2183:   }  //fpkLTOS()
  2184: 
  2185:   //fpkSTOH ()
  2186:   //  $FE12  __STOH
  2187:   //  16進数の文字列を32bit符号なし整数に変換する
  2188:   //  /^[0-9A-Fa-f]+/
  2189:   //  <a0.l:16進数の文字列の先頭
  2190:   //  >d0.l:32bit符号なし整数
  2191:   //  >a0.l:16進数の文字列の直後('\0'とは限らない)
  2192:   //  >ccr:0=エラーなし,N|C=文法エラー,V|C=オーバーフロー
  2193:   public static void fpkSTOH () throws M68kException {
  2194:     int a = XEiJ.regRn[8];  //a0
  2195:     int c = XEiJ.busRbz (a);
  2196:     if (!('0' <= c && c <= '9' || 'A' <= c && c <= 'F' || 'a' <= c && c <= 'f')) {  //数字が1つもない
  2197:       XEiJ.regRn[8] = a;  //a0
  2198:       XEiJ.regCCR = XEiJ.REG_CCR_N | XEiJ.REG_CCR_C;
  2199:       return;
  2200:     }
  2201:     int x = c <= '9' ? c - '0' : c <= 'F' ? c - ('A' - 10) : c - ('a' - 10);  //値
  2202:     for (c = XEiJ.busRbz (++a); '0' <= c && c <= '9' || 'A' <= c && c <= 'F' || 'a' <= c && c <= 'f'; c = XEiJ.busRbz (++a)) {
  2203:       if (0x0fffffff < x) {  //0xffffffffより大きくなるときオーバーフロー
  2204:         XEiJ.regRn[8] = a;  //a0
  2205:         XEiJ.regCCR = XEiJ.REG_CCR_V | XEiJ.REG_CCR_C;
  2206:         return;
  2207:       }
  2208:       x = x << 4 | (c <= '9' ? c - '0' : c <= 'F' ? c - ('A' - 10) : c - ('a' - 10));
  2209:     }
  2210:     XEiJ.regRn[0] = x;  //d0
  2211:     XEiJ.regRn[8] = a;  //a0
  2212:     XEiJ.regCCR = 0;
  2213:   }  //fpkSTOH()
  2214: 
  2215:   //fpkHTOS ()
  2216:   //  $FE13  __HTOS
  2217:   //  32bit符号なし整数を16進数の文字列に変換する
  2218:   //  /^[1-9A-F][0-9A-F]*$/
  2219:   //  <d0.l:32bit符号なし整数
  2220:   //  <a0.l:文字列バッファの先頭
  2221:   //  >a0.l:16進数の文字列の直後('\0'の位置)
  2222:   public static void fpkHTOS () throws M68kException {
  2223:     int x = XEiJ.regRn[0];  //d0
  2224:     int a = XEiJ.regRn[8] += Math.max (1, 35 - Integer.numberOfLeadingZeros (x) >> 2);  //a0
  2225:     XEiJ.busWb (a, 0);
  2226:     do {
  2227:       int t = x & 15;
  2228:       //     t             00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
  2229:       //   9-t             09 08 07 06 05 04 03 02 01 00 ff fe fd fc fb fa
  2230:       //   9-t>>4          00 00 00 00 00 00 00 00 00 00 ff ff ff ff ff ff
  2231:       //   9-t>>4&7        00 00 00 00 00 00 00 00 00 00 07 07 07 07 07 07
  2232:       //   9-t>>4&7|48     30 30 30 30 30 30 30 30 30 30 37 37 37 37 37 37
  2233:       //  (9-t>>4&7|48)+t  30 31 32 33 34 35 36 37 38 39 41 42 43 44 45 46
  2234:       //                    0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
  2235:       XEiJ.busWb (--a, (9 - t >> 4 & 7 | 48) + t);
  2236:     } while ((x >>>= 4) != 0);
  2237:   }  //fpkHTOS()
  2238: 
  2239:   //fpkSTOO ()
  2240:   //  $FE14  __STOO
  2241:   //  8進数の文字列を32bit符号なし整数に変換する
  2242:   //  /^[0-7]+/
  2243:   //  <a0.l:8進数の文字列の先頭
  2244:   //  >d0.l:32bit符号なし整数
  2245:   //  >a0.l:8進数の文字列の直後('\0'とは限らない)
  2246:   //  >ccr:0=エラーなし,N|C=文法エラー,V|C=オーバーフロー
  2247:   public static void fpkSTOO () throws M68kException {
  2248:     int a = XEiJ.regRn[8];  //a0
  2249:     int c = XEiJ.busRbz (a);
  2250:     if (!('0' <= c && c <= '7')) {  //数字が1つもない
  2251:       XEiJ.regRn[8] = a;  //a0
  2252:       XEiJ.regCCR = XEiJ.REG_CCR_N | XEiJ.REG_CCR_C;
  2253:       return;
  2254:     }
  2255:     int x = c - '0';  //値
  2256:     for (c = XEiJ.busRbz (++a); '0' <= c && c <= '7'; c = XEiJ.busRbz (++a)) {
  2257:       if (0x1fffffff < x) {  //0xffffffffより大きくなるときオーバーフロー
  2258:         XEiJ.regRn[8] = a;  //a0
  2259:         XEiJ.regCCR = XEiJ.REG_CCR_V | XEiJ.REG_CCR_C;
  2260:         return;
  2261:       }
  2262:       x = x << 3 | c & 7;
  2263:     }
  2264:     XEiJ.regRn[0] = x;  //d0
  2265:     XEiJ.regRn[8] = a;  //a0
  2266:     XEiJ.regCCR = 0;
  2267:   }  //fpkSTOO()
  2268: 
  2269:   //fpkOTOS ()
  2270:   //  $FE15  __OTOS
  2271:   //  32bit符号なし整数を8進数の文字列に変換する
  2272:   //  /^[1-7][0-7]*$/
  2273:   //  <d0.l:32bit符号なし整数
  2274:   //  <a0.l:文字列バッファの先頭
  2275:   //  >a0.l:8進数の文字列の直後('\0'の位置)
  2276:   public static void fpkOTOS () throws M68kException {
  2277:     int x = XEiJ.regRn[0];  //d0
  2278:     //perl optdiv.pl 34 3
  2279:     //  x/3==x*43>>>7 (0<=x<=127) [34*43==1462]
  2280:     int a = XEiJ.regRn[8] += Math.max (1, (34 - Integer.numberOfLeadingZeros (x)) * 43 >>> 7);  //a0
  2281:     XEiJ.busWb (a, 0);
  2282:     do {
  2283:       XEiJ.busWb (--a, '0' | x & 7);
  2284:     } while ((x >>>= 3) != 0);
  2285:   }  //fpkOTOS()
  2286: 
  2287:   //fpkSTOB ()
  2288:   //  $FE16  __STOB
  2289:   //  2進数の文字列を32bit符号なし整数に変換する
  2290:   //  /^[01]+/
  2291:   //  <a0.l:2進数の文字列の先頭
  2292:   //  >d0.l:32bit符号なし整数
  2293:   //  >a0.l:2進数の文字列の直後('\0'とは限らない)
  2294:   //  >ccr:0=エラーなし,N|C=文法エラー,V|C=オーバーフロー
  2295:   public static void fpkSTOB () throws M68kException {
  2296:     int a = XEiJ.regRn[8];  //a0
  2297:     int c = XEiJ.busRbz (a);
  2298:     if (!('0' <= c && c <= '1')) {  //数字が1つもない
  2299:       XEiJ.regRn[8] = a;  //a0
  2300:       XEiJ.regCCR = XEiJ.REG_CCR_N | XEiJ.REG_CCR_C;
  2301:       return;
  2302:     }
  2303:     int x = c - '0';  //値
  2304:     for (c = XEiJ.busRbz (++a); '0' <= c && c <= '1'; c = XEiJ.busRbz (++a)) {
  2305:       if (x < 0) {  //オーバーフロー
  2306:         XEiJ.regRn[8] = a;  //a0
  2307:         XEiJ.regCCR = XEiJ.REG_CCR_V | XEiJ.REG_CCR_C;
  2308:         return;
  2309:       }
  2310:       x = x << 1 | c & 1;
  2311:     }
  2312:     XEiJ.regRn[0] = x;  //d0
  2313:     XEiJ.regRn[8] = a;  //a0
  2314:     XEiJ.regCCR = 0;
  2315:   }  //fpkSTOB()
  2316: 
  2317:   //fpkBTOS ()
  2318:   //  $FE17  __BTOS
  2319:   //  32bit符号なし整数を2進数の文字列に変換する
  2320:   //  /^1[01]*$/
  2321:   //  <d0.l:32bit符号なし整数
  2322:   //  <a0.l:文字列バッファの先頭
  2323:   //  >a0.l:2進数の文字列の直後('\0'の位置)
  2324:   public static void fpkBTOS () throws M68kException {
  2325:     int x = XEiJ.regRn[0];  //d0
  2326:     int a = XEiJ.regRn[8] += Math.max (1, 32 - Integer.numberOfLeadingZeros (x));  //a0
  2327:     XEiJ.busWb (a, 0);
  2328:     do {
  2329:       XEiJ.busWb (--a, '0' | x & 1);
  2330:     } while ((x >>>= 1) != 0);
  2331:   }  //fpkBTOS()
  2332: 
  2333:   //fpkIUSING ()
  2334:   //  $FE18  __IUSING
  2335:   //  32bit符号あり整数を文字数を指定して右詰めで10進数の文字列に変換する
  2336:   //  /^ *-?[1-9][0-9]*$/
  2337:   //  <d0.l:32bit符号あり整数
  2338:   //  <d1.b:文字数
  2339:   //  <a0.l:文字列バッファの先頭
  2340:   //  >a0.l:10進数の文字列の直後('\0'の位置)
  2341:   public static void fpkIUSING () throws M68kException {
  2342:     int x = XEiJ.regRn[0];  //d0
  2343:     int n = 0;  //符号の文字数
  2344:     if (x < 0) {  //負
  2345:       n = 1;
  2346:       x = -x;
  2347:     }
  2348:     long t = XEiJ.fmtBcd12 (0xffffffffL & x);  //符号は取り除いてあるがx=0x80000000の場合があるので(long)xは不可
  2349:     int l = n + Math.max (1, 67 - Long.numberOfLeadingZeros (t) >> 2);  //符号を含めた文字数
  2350:     int a = XEiJ.regRn[8];  //a0
  2351:     for (int i = (XEiJ.regRn[1] & 255) - l; i > 0; i--) {
  2352:       XEiJ.busWb (a++, ' ');
  2353:     }
  2354:     XEiJ.regRn[8] = a += l;  //a0
  2355:     XEiJ.busWb (a, 0);
  2356:     do {
  2357:       XEiJ.busWb (--a, '0' | (int) t & 15);
  2358:     } while ((t >>>= 4) != 0L);
  2359:     if (n != 0) {
  2360:       XEiJ.busWb (--a, '-');
  2361:     }
  2362:   }  //fpkIUSING()
  2363: 
  2364:   //fpkVAL ()
  2365:   //  $FE20  __VAL
  2366:   //  文字列を64bit浮動小数点数に変換する
  2367:   //  先頭の'\t'と' 'を読み飛ばす
  2368:   //  "&B"または"&b"で始まっているときは続きを2進数とみなして__STOBで32bit符号なし整数に変換してから__LTODで64bit浮動小数点数に変換する
  2369:   //  "&O"または"&o"で始まっているときは続きを8進数とみなして__STOOで32bit符号なし整数に変換してから__LTODで64bit浮動小数点数に変換する
  2370:   //  "&H"または"&h"で始まっているときは続きを16進数とみなして__STOHで32bit符号なし整数に変換してから__LTODで64bit浮動小数点数に変換する
  2371:   //  それ以外は__STODと同じ
  2372:   //  <a0.l:文字列の先頭
  2373:   //  >d0d1.d:64bit浮動小数点数
  2374:   //  >d2.l:(先頭が'&'でないとき)65535=64bit浮動小数点数をオーバーフローなしでintに変換できる,0=それ以外
  2375:   //  >d3.l:(先頭が'&'でないとき)d2.l==65535のとき64bit浮動小数点数をintに変換した値
  2376:   //  >a0.l:変換された文字列の直後('\0'とは限らない)
  2377:   //  >ccr:0=エラーなし,N|C=文法エラー,V|C=オーバーフロー
  2378:   public static void fpkVAL () throws M68kException {
  2379:     int a = XEiJ.regRn[8];  //a0
  2380:     //先頭の空白を読み飛ばす
  2381:     int c = XEiJ.busRbs (a++);
  2382:     while (c == ' ' || c == '\t') {
  2383:       c = XEiJ.busRbs (a++);
  2384:     }
  2385:     if (c == '&') {  //&B,&O,&H
  2386:       c = XEiJ.busRbs (a++) & 0xdf;
  2387:       XEiJ.regRn[8] = a;  //&?の直後
  2388:       if (c == 'B') {
  2389:         fpkSTOB ();
  2390:         fpkLTOD ();
  2391:       } else if (c == 'O') {
  2392:         fpkSTOO ();
  2393:         fpkLTOD ();
  2394:       } else if (c == 'H') {
  2395:         fpkSTOH ();
  2396:         fpkLTOD ();
  2397:       } else {
  2398:         XEiJ.regCCR = XEiJ.REG_CCR_N | XEiJ.REG_CCR_C;  //文法エラー
  2399:       }
  2400:     } else {  //&B,&O,&H以外
  2401:       fpkSTOD ();
  2402:     }
  2403:   }  //fpkVAL()
  2404: 
  2405:   //fpkUSING ()
  2406:   //  $FE21  __USING
  2407:   //  64bit浮動小数点数をアトリビュートを指定して文字列に変換する
  2408:   //  メモ
  2409:   //    bit1の'\\'とbit4の'+'を両方指定したときは'\\'が右側。先頭に"+\\"を付ける
  2410:   //    bit1の'\\'とbit2の','とbit4の'+'は整数部の桁数が足りないとき数字を右にずらして押し込まれる
  2411:   //    bit3で指数形式を指示しなければ指数部が極端に大きくても極端に小さくても指数形式にならない
  2412:   //    bit3で指数形式を指定したときbit1の'\\'とbit2の','は無効
  2413:   //    bit4とbit5とbit6はbit4>bit5>bit6の順位で1つだけ有効
  2414:   //    有効数字は14桁で15桁目以降はすべて0
  2415:   //    FLOAT2.Xは整数部の0でない最初の数字から256文字目までで打ち切られてしまう
  2416:   //    整数部の桁数に余裕があれば左側の空白は出力されるので文字列の全体が常に256バイトに収まるわけではない
  2417:   //      using 1234.5 5 0 0    " 1235."
  2418:   //      using 1234.5 5 1 0    " 1234.5"
  2419:   //      using 1234.5 5 2 0    " 1234.50"
  2420:   //      using 1234.5 6 2 1    "**1234.50"
  2421:   //      using 1234.5 6 2 2    " \\1234.50"
  2422:   //      using 1234.5 6 2 3    "*\\1234.50"
  2423:   //      using 1234.5 6 2 4    " 1,234.50"
  2424:   //      using 1234.5 4 2 4    "1,234.50"
  2425:   //      using 1234.5 4 2 5    "1,234.50"
  2426:   //      using 1234.5 4 2 6    "\\1,234.50"
  2427:   //      using 1234.5 4 2 7    "\\1,234.50"
  2428:   //      using 1234.5 4 2 16   "+1234.50"
  2429:   //      using 1234.5 4 2 22   "+\\1,234.50"
  2430:   //      using 1234.5 4 2 32   "1234.50+"
  2431:   //      using 1234.5 4 2 48   "+1234.50"
  2432:   //      using 1234.5 4 2 64   "1234.50 "
  2433:   //      using 1234.5 4 2 80   "+1234.50"
  2434:   //      using 1234.5 4 2 96   "1234.50+"
  2435:   //      using 12345678901234567890 10 1 0      "12345678901235000000.0"
  2436:   //      using 12345678901234567890e+10 10 1 0  "123456789012350000000000000000.0"
  2437:   //      using 0.3333 0 0 0    "."
  2438:   //      using 0.6666 0 0 0    "1."
  2439:   //      using 0.6666 0 3 0    ".667"
  2440:   //      using 0.6666 3 0 0    "  1."
  2441:   //      using 0.3333 0 0 2    "\\."
  2442:   //      using 0.3333 0 0 16   "+."
  2443:   //      using 0.3333 0 0 18   "+\\."
  2444:   //      using 1e-10 3 3 0     "  0.000"
  2445:   //    指数形式の出力は不可解で本来の動作ではないように思えるが、
  2446:   //    X-BASICのprint using命令が使っているのでFLOAT2.Xに合わせておいた方がよさそう
  2447:   //      print using "###.##";1.23         "  1.23"         整数部の桁数は3
  2448:   //      print using "+##.##";1.23         " +1.23"         整数部の桁数は3←
  2449:   //      print using "###.##^^^^^";1.23    " 12.30E-001"    整数部の桁数は3
  2450:   //      print using "+##.##^^^^^";1.23    "+12.30E-001"    整数部の桁数は2←
  2451:   //    FLOAT2.Xでは#NANと#INFは4桁の整数のように出力される。末尾に小数点が付くが小数部には何も出力されない
  2452:   //      using -#INF 7 3 23     "*-\\#,INF."
  2453:   //    FLOAT2.Xで#NANと#INFを指数形式にするとさらに不可解。これはバグと言ってよいと思う
  2454:   //      using #INF 10 10 8      " #INFE-005"
  2455:   //    ここでは#NANと#INFは整数部と小数点と小数部と指数部の全体を使って右寄せにする
  2456:   //  <d0d1.d:64bit浮動小数点数
  2457:   //  <d2.l:整数部の桁数
  2458:   //  <d3.l:小数部の桁数
  2459:   //  <d4.l:アトリビュート
  2460:   //    bit0  左側を'*'で埋める
  2461:   //    bit1  先頭に'\\'を付ける
  2462:   //    bit2  整数部を3桁毎に','で区切る
  2463:   //    bit3  指数形式
  2464:   //    bit4  先頭に符号('+'または'-')を付ける
  2465:   //    bit5  末尾に符号('+'または'-')を付ける
  2466:   //    bit6  末尾に符号(' 'または'-')を付ける
  2467:   //  <a0.l:文字列バッファの先頭
  2468:   //  a0は変化しない
  2469:   public static void fpkUSING () throws M68kException {
  2470:     fpkUSINGSub ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1]);  //64bit浮動小数点数
  2471:   }  //fpkUSING()
  2472:   public static void fpkUSINGSub (long l) throws M68kException {
  2473:     int len1 = Math.max (0, XEiJ.regRn[2]);  //整数部の桁数
  2474:     int len2 = Math.max (0, XEiJ.regRn[3]);  //小数部の桁数
  2475:     int attr = XEiJ.regRn[4];  //アトリビュート
  2476:     int a = XEiJ.regRn[8];  //文字列バッファの先頭
  2477:     boolean exp = (attr & 8) != 0;  //true=指数形式
  2478:     int spc = (attr & 1) != 0 ? '*' : ' ';  //先頭の空白を充填する文字
  2479:     int yen = (attr & 2) != 0 ? '\\' : 0;  //先頭の'\\'
  2480:     int cmm = !exp && (attr & 4) != 0 ? ',' : 0;  //3桁毎に入れる','
  2481:     //符号
  2482:     int sgn1 = 0;  //先頭の符号
  2483:     int sgn2 = 0;  //末尾の符号
  2484:     if (l < 0L) {  //負
  2485:       if ((attr & 32 + 64) == 0) {  //末尾に符号を付けない
  2486:         sgn1 = '-';  //先頭の符号
  2487:       } else {  //末尾に符号を付ける
  2488:         sgn2 = '-';  //末尾の符号
  2489:       }
  2490:       l &= 0x7fffffffffffffffL;  //符号bitを消しておく
  2491:     } else {  //正
  2492:       if ((attr & 16) != 0) {  //先頭に符号('+'または'-')を付ける
  2493:         sgn1 = '+';
  2494:       } else if ((attr & 16 + 32) == 32) {  //末尾に符号('+'または'-')を付ける
  2495:         sgn2 = '+';
  2496:       } else if ((attr & 16 + 32 + 64) == 64) {  //末尾に符号(' 'または'-')を付ける
  2497:         sgn2 = ' ';
  2498:       }
  2499:     }
  2500:     double x = Double.longBitsToDouble (l);  //絶対値
  2501:     int e = (int) (l >>> 52) - 1023;  //指数部。ゲタ0。符号bitは消してあるのでマスクは不要
  2502:     l &= 0x000fffffffffffffL;  //仮数部の小数部。正規化数のとき整数部の1が付いていないことに注意
  2503:     //±0,±Inf,NaN
  2504:     if (e == -1023) {  //±0,非正規化数
  2505:       if (l == 0L) {  //±0
  2506:         for (int i = len1 - ((sgn1 != 0 ? 1 : 0) +  //先頭の符号
  2507:                              (yen != 0 ? 1 : 0) +  //'\\'
  2508:                              1  //数字
  2509:                              ); 0 < i; i--) {
  2510:           XEiJ.busWb (a++, spc);  //空白
  2511:         }
  2512:         if (sgn1 != 0) {
  2513:           XEiJ.busWb (a++, sgn1);  //先頭の符号
  2514:         }
  2515:         if (yen != 0) {
  2516:           XEiJ.busWb (a++, yen);  //'\\'
  2517:         }
  2518:         if (0 < len1) {
  2519:           XEiJ.busWb (a++, '0');  //整数部
  2520:         }
  2521:         XEiJ.busWb (a++, '.');  //小数点
  2522:         for (; 0 < len2; len2--) {
  2523:           XEiJ.busWb (a++, '0');  //小数部
  2524:         }
  2525:         XEiJ.busWb (a, '\0');
  2526:         return;
  2527:       }
  2528:       e -= Long.numberOfLeadingZeros (l) - 12;  //非正規化数の指数部を補正する
  2529:     } else if (e == 1024) {  //±Inf,NaN
  2530:       for (int i = len1 + 1 + len2 + (exp ? 5 : 0) -  //整数部と小数点と小数部と指数部の全体を使って右寄せにする
  2531:            ((sgn1 != 0 ? 1 : 0) +  //先頭の符号
  2532:             (yen != 0 ? 1 : 0) +  //'\\'
  2533:             4  //文字
  2534:             ); 0 < i; i--) {
  2535:         XEiJ.busWb (a++, spc);  //空白
  2536:       }
  2537:       if (sgn1 != 0) {
  2538:         XEiJ.busWb (a++, sgn1);  //先頭の符号
  2539:       }
  2540:       if (yen != 0) {
  2541:         XEiJ.busWb (a++, yen);  //'\\'
  2542:       }
  2543:       XEiJ.busWb (a++, '#');
  2544:       if (l == 0L) {  //±Inf
  2545:         XEiJ.busWb (a++, 'I');
  2546:         XEiJ.busWb (a++, 'N');
  2547:         XEiJ.busWb (a++, 'F');
  2548:       } else {  //NaN
  2549:         XEiJ.busWb (a++, 'N');
  2550:         XEiJ.busWb (a++, 'A');
  2551:         XEiJ.busWb (a++, 'N');
  2552:       }
  2553:       XEiJ.busWb (a, '\0');
  2554:       return;
  2555:     }
  2556:     //10進数で表現したときの指数部を求める
  2557:     //  10^e<=x<10^(e+1)となるeを求める
  2558:     e = (int) Math.floor ((double) e * 0.30102999566398119521373889472);  //log10(2)
  2559:     //10^-eを掛けて1<=x<10にする
  2560:     //  非正規化数の最小値から正規化数の最大値まで処理できなければならない
  2561:     //  10^-eを計算してからまとめて掛ける方法はxが非正規化数のとき10^-eがオーバーフローしてしまうので不可
  2562:     //    doubleは非正規化数の逆数を表現できない
  2563:     if (0 < e) {  //10<=x
  2564:       x *= FPK_TEN_M16QR[e & 15];
  2565:       if (16 <= e) {
  2566:         x *= FPK_TEN_M16QR[16 + (e >> 4 & 15)];
  2567:         if (256 <= e) {
  2568:           x *= FPK_TEN_M16QR[33];  //FPK_TEN_M16QR[32 + (e >> 8)]
  2569:         }
  2570:       }
  2571:     } else if (e < 0) {  //x<1
  2572:       x *= FPK_TEN_P16QR[-e & 15];
  2573:       if (e <= -16) {
  2574:         x *= FPK_TEN_P16QR[16 + (-e >> 4 & 15)];
  2575:         if (e <= -256) {
  2576:           x *= FPK_TEN_P16QR[33];  //FPK_TEN_P16QR[32 + (-e >> 8)]
  2577:         }
  2578:       }
  2579:     }
  2580:     //整数部2桁、小数部16桁の10進数に変換する
  2581:     //  1<=x<10なのでw[1]が先頭になるはずだが誤差で前後にずれる可能性がある
  2582:     int[] w = new int[18];
  2583:     {
  2584:       int d = (int) x;
  2585:       int t = XEiJ.FMT_BCD4[d];
  2586:       w[0] = t >> 4;
  2587:       w[1] = t      & 15;
  2588:       for (int i = 2; i < 18; i += 4) {
  2589:         //xを10000倍して整数部dを引くことで小数部を残すが、このとき情報落ちが発生して誤差が蓄積する
  2590:         //Double-Doubleの乗算の要領で10000倍を正確に行い、誤差の蓄積を回避する
  2591:         //x = (x - (double) d) * 10000.0;
  2592:         double xh = x * 0x8000001p0;
  2593:         xh += x - xh;  //xの上半分
  2594:         x = (xh - (double) d) * 10000.0 + (x - xh) * 10000.0;
  2595:         d = (int) x;
  2596:         t = XEiJ.FMT_BCD4[d];
  2597:         w[i    ] = t >> 12;
  2598:         w[i + 1] = t >>  8 & 15;
  2599:         w[i + 2] = t >>  4 & 15;
  2600:         w[i + 3] = t       & 15;
  2601:       }
  2602:     }
  2603:     //先頭の位置を確認する
  2604:     //  w[h]が先頭(0でない最初の数字)の位置
  2605:     int h = w[0] != 0 ? 0 : w[1] != 0 ? 1 : 2;
  2606:     //14+1桁目を四捨五入する
  2607:     int o = h + 14;  //w[o]は四捨五入する桁の位置。w[]の範囲内
  2608:     if (5 <= w[o]) {
  2609:       int i = o;
  2610:       while (10 <= ++w[--i]) {
  2611:         w[i] = 0;
  2612:       }
  2613:       if (i < h) {  //先頭から繰り上がった。このとき新しい先頭は1でそれ以外はすべて0
  2614:         h--;  //先頭を左にずらす
  2615:         o--;  //末尾を左にずらす
  2616:       }
  2617:     }
  2618:     //先頭の位置に応じて指数部を更新する
  2619:     //  w[h]が整数部、w[h+1..13]が小数部。10^eの小数点はw[h]の右側。整数部の桁数はe+1桁
  2620:     e -= h - 1;
  2621:     //整数部の桁数を調節する
  2622:     int ee = !exp ? e : Math.max (0, sgn1 != 0 || sgn2 != 0 ? len1 : len1 - 1) - 1;  //整数部の桁数-1。整数部の桁数はee+1桁。指数部はe-ee
  2623:     //小数点以下len2+1桁目が先頭から14+1桁目よりも左側にあるときその桁で改めて四捨五入する
  2624:     //  あらかじめ14+1桁目で四捨五入しておかないと、
  2625:     //  1.5の5を四捨五入しなければならないときに誤差で1.499…になったまま4を四捨五入しようとして失敗することがある
  2626:     int s = h + ee + 1 + len2;  //w[s]は小数点以下len2+1桁目の位置。w.length<=sの場合があることに注意
  2627:     if (s < o) {
  2628:       o = s;  //w[o]は四捨五入する桁の位置。o<0の場合があることに注意
  2629:       if (0 <= o && 5 <= w[o]) {
  2630:         int i = o;
  2631:         while (10 <= ++w[--i]) {
  2632:           w[i] = 0;
  2633:         }
  2634:         if (i < h) {  //先頭から繰り上がった。このとき新しい先頭は1でそれ以外はすべて0
  2635:           h--;  //先頭を左にずらす
  2636:           if (!exp) {  //指数形式でないとき
  2637:             ee++;  //左に1桁伸ばす。全体の桁数が1桁増える
  2638:           } else {  //指数形式のとき
  2639:             e++;  //指数部を1増やす
  2640:             o--;  //末尾を左にずらす。全体の桁数は変わらない
  2641:           }
  2642:         }
  2643:       }
  2644:     }
  2645:     //文字列に変換する
  2646:     if (0 <= ee) {  //1<=x
  2647:       for (int i = len1 - ((sgn1 != 0 ? 1 : 0) +  //先頭の符号
  2648:                            (yen != 0 ? 1 : 0) +  //'\\'
  2649:                            (cmm != 0 ? ee / 3 : 0) +  //','
  2650:                            ee + 1  //数字
  2651:                            ); 0 < i; i--) {
  2652:         XEiJ.busWb (a++, spc);  //空白
  2653:       }
  2654:       if (sgn1 != 0) {
  2655:         XEiJ.busWb (a++, sgn1);  //先頭の符号
  2656:       }
  2657:       if (yen != 0) {
  2658:         XEiJ.busWb (a++, yen);  //'\\'
  2659:       }
  2660:       for (int i = ee; 0 <= i; i--) {
  2661:         XEiJ.busWb (a++, h < o ? '0' + w[h] : '0');  //整数部
  2662:         h++;
  2663:         if (cmm != 0 && 0 < i && i % 3 == 0) {
  2664:           XEiJ.busWb (a++, cmm);  //','
  2665:         }
  2666:       }
  2667:       XEiJ.busWb (a++, '.');  //小数点
  2668:       for (; 0 < len2; len2--) {
  2669:         XEiJ.busWb (a++, h < o ? '0' + w[h] : '0');  //小数部
  2670:         h++;
  2671:       }
  2672:     } else {  //x<1
  2673:       for (int i = len1 - ((sgn1 != 0 ? 1 : 0) +  //先頭の符号
  2674:                            (yen != 0 ? 1 : 0) +  //'\\'
  2675:                            1  //数字
  2676:                            ); 0 < i; i--) {
  2677:         XEiJ.busWb (a++, spc);  //空白
  2678:       }
  2679:       if (sgn1 != 0) {
  2680:         XEiJ.busWb (a++, sgn1);  //先頭の符号
  2681:       }
  2682:       if (yen != 0) {
  2683:         XEiJ.busWb (a++, yen);  //'\\'
  2684:       }
  2685:       if (0 < len1) {
  2686:         XEiJ.busWb (a++, '0');  //整数部
  2687:       }
  2688:       XEiJ.busWb (a++, '.');  //小数点
  2689:       for (int i = -1 - ee; 0 < len2 && 0 < i; len2--, i--) {
  2690:         XEiJ.busWb (a++, '0');  //小数部の先頭の0の並び
  2691:       }
  2692:       for (; 0 < len2; len2--) {
  2693:         XEiJ.busWb (a++, h < o ? '0' + w[h] : '0');  //小数部
  2694:         h++;
  2695:       }
  2696:     }
  2697:     if (exp) {
  2698:       e -= ee;
  2699:       XEiJ.busWb (a++, 'E');  //指数部の始まり
  2700:       if (0 <= e) {
  2701:         XEiJ.busWb (a++, '+');  //指数部の正符号。省略しない
  2702:       } else {
  2703:         XEiJ.busWb (a++, '-');  //指数部の負符号
  2704:         e = -e;
  2705:       }
  2706:       e = XEiJ.FMT_BCD4[e];
  2707:       XEiJ.busWb (a++, '0' + (e >> 8     ));  //指数部の100の位。0でも省略しない
  2708:       XEiJ.busWb (a++, '0' + (e >> 4 & 15));  //指数部の10の位
  2709:       XEiJ.busWb (a++, '0' + (e      & 15));  //指数部の1の位
  2710:     }
  2711:     if (sgn2 != 0) {
  2712:       XEiJ.busWb (a++, sgn2);  //末尾の符号
  2713:     }
  2714:     XEiJ.busWb (a, '\0');
  2715:   }  //fpkUSINGSub0(long)
  2716: 
  2717:   //fpkSTOD ()
  2718:   //  $FE22  __STOD
  2719:   //  文字列を64bit浮動小数点数に変換する
  2720:   //  先頭の'\t'と' 'を読み飛ばす
  2721:   //  "#INF"は無限大、"#NAN"は非数とみなす
  2722:   //  バグ
  2723:   //    FLOAT2.X 2.02/2.03は誤差が大きい
  2724:   //      "1.7976931348623E+308"=0x7fefffffffffffb0が0x7fefffffffffffb3になる
  2725:   //      "1.5707963267949"=0x3ff921fb54442d28が0x3ff921fb54442d26になる
  2726:   //      "4.9406564584125E-324"(非正規化数の最小値よりもわずかに大きい)がエラーになる
  2727:   //    FLOAT2.X 2.02/2.03は"-0"が+0になる
  2728:   //    FLOAT4.X 1.02は"-0"が+0になる(実機で確認済み)
  2729:   //    FLOAT2.X 2.02/2.03は"-#INF"が+Infになる
  2730:   //      print val("-#INF")で再現できる
  2731:   //      '-'を符号として解釈しておきながら結果の無限大に符号を付けるのを忘れている
  2732:   //    FLOAT2.X 2.02/2.03は".#INF"が+Infになる
  2733:   //      print val(".#INF")で再現できる
  2734:   //    FLOAT4.X 1.02は"#NAN","#INF","-#INF"を読み取ったときa0が文字列の直後ではなく最後の文字を指している
  2735:   //  <a0.l:文字列の先頭
  2736:   //  >d0d1.d:64bit浮動小数点数
  2737:   //  >d2.l:65535=64bit浮動小数点数をオーバーフローなしでintに変換できる,0=それ以外
  2738:   //  >d3.l:d2.l==65535のとき64bit浮動小数点数をintに変換した値
  2739:   //  >a0.l:変換された文字列の直後('\0'とは限らない)
  2740:   //  >ccr:0=エラーなし,N|C=文法エラー,V|C=オーバーフロー
  2741:   public static void fpkSTOD () throws M68kException {
  2742:     long l = Double.doubleToLongBits (fpkSTODSub ());
  2743:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
  2744:       l = 0x7fffffffffffffffL;
  2745:     }
  2746:     XEiJ.regRn[0] = (int) (l >> 32);  //d0
  2747:     XEiJ.regRn[1] = (int) l;  //d1
  2748:   }  //fpkSTOD()
  2749:   public static double fpkSTODSub () throws M68kException {
  2750:     int a = XEiJ.regRn[8];  //a0
  2751:     //先頭の空白を読み飛ばす
  2752:     int c = XEiJ.busRbs (a);
  2753:     while (c == ' ' || c == '\t') {
  2754:       c = XEiJ.busRbs (++a);
  2755:     }
  2756:     //符号を読み取る
  2757:     double s = 1.0;  //仮数部の符号
  2758:     if (c == '+') {
  2759:       c = XEiJ.busRbs (++a);
  2760:     } else if (c == '-') {
  2761:       s = -s;
  2762:       c = XEiJ.busRbs (++a);
  2763:     }
  2764:     //#NANと#INFを処理する
  2765:     if (c == '#') {
  2766:       c = XEiJ.busRbs (a + 1);
  2767:       if (c == 'N' || c == 'I') {  //小文字は不可
  2768:         c = c << 8 | XEiJ.busRbz (a + 2);
  2769:         if (c == ('N' << 8 | 'A') || c == ('I' << 8 | 'N')) {
  2770:           c = c << 8 | XEiJ.busRbz (a + 3);
  2771:           if (c == ('N' << 16 | 'A' << 8 | 'N') || c == ('I' << 16 | 'N' << 8 | 'F')) {
  2772:             XEiJ.regRn[2] = 0;  //d2
  2773:             XEiJ.regRn[3] = 0;  //d3
  2774:             XEiJ.regRn[8] = a + 4;  //a0。"#NAN"または"#INF"のときだけ直後まで進める。それ以外は'#'の位置で止める
  2775:             XEiJ.regCCR = 0;  //エラーなし。"#INF"はオーバーフローとみなされない
  2776:             return c == ('N' << 16 | 'A' << 8 | 'N') ? Double.NaN : s * Double.POSITIVE_INFINITY;
  2777:           }
  2778:         }
  2779:       }
  2780:       XEiJ.regRn[8] = a;  //a0。'#'の位置で止める
  2781:       XEiJ.regCCR = XEiJ.REG_CCR_N | XEiJ.REG_CCR_C;  //文法エラー
  2782:       return 0.0;
  2783:     }  //if c=='#'
  2784:     //仮数部を読み取る
  2785:     //  数字を1000個並べてからe-1000などと書いてあるとき途中でオーバーフローすると困るので、
  2786:     //  多すぎる数字の並びは先頭の有効数字だけ読み取って残りは桁数だけ数えて読み飛ばす
  2787:     long u = 0L;  //仮数部
  2788:     int n = 0;  //0以外の最初の数字から数えて何桁目か
  2789:     int e = 1;  //-小数部の桁数。1=整数部
  2790:     if (c == '.') {  //仮数部の先頭が小数点
  2791:       e = 0;  //小数部開始
  2792:       c = XEiJ.busRbs (++a);
  2793:     }
  2794:     if (c < '0' || '9' < c) {  //仮数部に数字がない
  2795:       XEiJ.regRn[8] = a;  //a0
  2796:       XEiJ.regCCR = XEiJ.REG_CCR_N | XEiJ.REG_CCR_C;  //文法エラー
  2797:       return 0.0;
  2798:     }
  2799:     double x = 0.0;
  2800:     do {
  2801:       if (0 < n || '0' < c) {  //0以外
  2802:         n++;  //0以外の最初の数字から数えて何桁目か
  2803:       }
  2804:       if (e <= 0 && n <= 18) {  //小数部で18桁目まで
  2805:         e--;  //-小数部の桁数
  2806:       }
  2807:       if (0 < n && n <= 18) {  //1桁目から18桁目まで
  2808:         u = u * 10L + (long) (c - '0');
  2809:       }
  2810:       c = XEiJ.busRbs (++a);
  2811:       if (0 < e && c == '.') {  //整数部で小数点が出てきた
  2812:         e = 0;  //小数部開始
  2813:         c = XEiJ.busRbs (++a);
  2814:       }
  2815:     } while ('0' <= c && c <= '9');
  2816:     if (0 < e) {  //小数点が出てこなかった
  2817:       e = 18 < n ? n - 18 : 0;  //整数部を読み飛ばした桁数が(-小数部の桁数)
  2818:     }
  2819:     //  1<=u<10^18  整数なので誤差はない
  2820:     //  0<e   小数点がなくて整数部が19桁以上あって末尾を読み飛ばした
  2821:     //  e==0  小数点がなくて整数部が18桁以内で末尾を読み飛ばさなかった
  2822:     //        小数点があって小数点で終わっていた
  2823:     //  e<0   小数点があって小数部が1桁以上あった
  2824:     //指数部を読み取る
  2825:     if (c == 'E' || c == 'e') {
  2826:       c = XEiJ.busRbs (++a);
  2827:       int t = 1;  //指数部の符号
  2828:       if (c == '+') {
  2829:         c = XEiJ.busRbs (++a);
  2830:       } else if (c == '-') {
  2831:         t = -t;
  2832:         c = XEiJ.busRbs (++a);
  2833:       }
  2834:       if (c < '0' || '9' < c) {  //指数部に数字がない
  2835:         XEiJ.regRn[8] = a;  //a0
  2836:         XEiJ.regCCR = XEiJ.REG_CCR_N | XEiJ.REG_CCR_C;  //文法エラー
  2837:         return 0.0;
  2838:       }
  2839:       while (c == '0') {  //先頭の0を読み飛ばす
  2840:         c = XEiJ.busRbs (++a);
  2841:       }
  2842:       int p = 0;
  2843:       for (int j = 0; '0' <= c && c <= '9' && j < 9; j++) {  //0以外の数字が出てきてから最大で9桁目まで読み取る。Human68kの環境では数字を1GBも並べることはできないのでオーバーフローの判定には9桁あれば十分
  2844:         p = p * 10 + (c - '0');
  2845:         c = XEiJ.busRbs (++a);
  2846:       }
  2847:       e += t * p;
  2848:     }
  2849:     //符号と仮数部と指数部を合わせる
  2850:     //  x=s*x*10^e
  2851:     //  1<=u<10^18なのでeが範囲を大きく外れている場合を先に除外する
  2852:     if (e < -350) {
  2853:       XEiJ.regRn[2] = 65535;  //d2。-1ではない
  2854:       XEiJ.regRn[3] = 0;  //d3
  2855:       XEiJ.regRn[8] = a;  //a0
  2856:       XEiJ.regCCR = 0;  //エラーなし。アンダーフローはエラーとみなされない
  2857:       return s < 0.0 ? -0.0 : 0.0;
  2858:     }
  2859:     if (350 < e) {
  2860:       XEiJ.regRn[2] = 0;  //d2
  2861:       XEiJ.regRn[3] = 0;  //d3
  2862:       XEiJ.regRn[8] = a;  //a0
  2863:       XEiJ.regCCR = XEiJ.REG_CCR_V | XEiJ.REG_CCR_C;  //オーバーフロー
  2864:       return s * Double.POSITIVE_INFINITY;
  2865:     }
  2866:     if (true) {
  2867:       QFP xx = new QFP (s < 0.0 ? -u : u);  //符号と仮数部
  2868:       if (0 < e) {
  2869:         xx.mul (QFP.QFP_TEN_P16QR[e & 15]);
  2870:         if (16 <= e) {
  2871:           xx.mul (QFP.QFP_TEN_P16QR[16 + (e >> 4 & 15)]);
  2872:           if (256 <= e) {
  2873:             xx.mul (QFP.QFP_TEN_P16QR[33]);
  2874:           }
  2875:         }
  2876:       } else if (e < 0) {
  2877:         xx.mul (QFP.QFP_TEN_M16QR[-e & 15]);
  2878:         if (e <= -16) {
  2879:           xx.mul (QFP.QFP_TEN_M16QR[16 + (-e >> 4 & 15)]);
  2880:           if (e <= -256) {
  2881:             xx.mul (QFP.QFP_TEN_M16QR[33]);
  2882:           }
  2883:         }
  2884:       }
  2885:       x = xx.getd ();
  2886:     } else {
  2887:       x = s * (double) u;  //符号と仮数部
  2888:       if (0 < e) {
  2889:         x *= FPK_TEN_P16QR[e & 15];
  2890:         if (16 <= e) {
  2891:           x *= FPK_TEN_P16QR[16 + (e >> 4 & 15)];
  2892:           if (256 <= e) {
  2893:             x *= FPK_TEN_P16QR[33];  //FPK_TEN_P16QR[32 + (e >> 8)]
  2894:           }
  2895:         }
  2896:       } else if (e < 0) {
  2897:         x /= FPK_TEN_P16QR[-e & 15];
  2898:         if (e <= -16) {
  2899:           x /= FPK_TEN_P16QR[16 + (-e >> 4 & 15)];
  2900:           if (e <= -256) {
  2901:             x /= FPK_TEN_P16QR[33];  //FPK_TEN_P16QR[32 + (-e >> 8)]
  2902:           }
  2903:         }
  2904:       }
  2905:     }
  2906:     if (Double.isInfinite (x)) {
  2907:       XEiJ.regRn[8] = a;  //a0
  2908:       XEiJ.regCCR = XEiJ.REG_CCR_V | XEiJ.REG_CCR_C;  //オーバーフロー
  2909:       return x;
  2910:     }
  2911:     //  アンダーフローで0になっている場合がある
  2912:     if (x == (double) ((int) x)) {  //intで表現できる。+0.0==-0.0==0なので±0.0を含む
  2913:       XEiJ.regRn[2] = 65535;  //d2。-1ではない
  2914:       XEiJ.regRn[3] = (int) x;  //d3
  2915:     } else {  //intで表現できない
  2916:       XEiJ.regRn[2] = 0;  //d2
  2917:       XEiJ.regRn[3] = 0;  //d3
  2918:     }
  2919:     XEiJ.regRn[8] = a;  //a0
  2920:     XEiJ.regCCR = 0;  //エラーなし
  2921:     return x;
  2922:   }  //fpkSTODSub()
  2923: 
  2924:   //fpkDTOS ()
  2925:   //  $FE23  __DTOS
  2926:   //  64bit浮動小数点数を文字列に変換する
  2927:   //  無限大は"#INF"、非数は"#NAN"になる
  2928:   //  指数形式の境目
  2929:   //    x<10^-4または10^14<=xのとき指数形式にする
  2930:   //    FLOAT2.X/FLOAT4.Xの場合
  2931:   //      3f2fffffffffff47  2.4414062499999E-004
  2932:   //      3f2fffffffffff48  0.000244140625
  2933:   //      42d6bcc41e8fffdf  99999999999999
  2934:   //      42d6bcc41e8fffe0  1E+014
  2935:   //  <d0d1.d:64bit浮動小数点数
  2936:   //  <a0.l:文字列バッファの先頭
  2937:   //  >a0.l:末尾の'\0'の位置
  2938:   public static void fpkDTOS () throws M68kException {
  2939:     fpkDTOSSub ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1]);  //64bit浮動小数点数
  2940:   }  //fpkDTOS()
  2941:   public static void fpkDTOSSub (long l) throws M68kException {
  2942:     final int len3 = 14;
  2943:     int a = XEiJ.regRn[8];  //文字列バッファの先頭
  2944:     //符号と指数部の処理
  2945:     //  ±0,±Inf,NaNはここで除外する
  2946:     if (l < 0L) {
  2947:       XEiJ.busWb (a++, '-');  //負符号
  2948:       l &= 0x7fffffffffffffffL;  //符号bitを消しておく
  2949:     }
  2950:     double x = Double.longBitsToDouble (l);  //絶対値
  2951:     int e = (int) (l >>> 52) - 1023;  //指数部。ゲタ0。符号bitは消してあるのでマスクは不要
  2952:     l &= 0x000fffffffffffffL;  //仮数部の小数部。正規化数のとき整数部の1が付いていないことに注意
  2953:     if (e == -1023) {  //±0,非正規化数
  2954:       if (l == 0L) {  //±0
  2955:         XEiJ.busWb (a++, '0');  //0
  2956:         XEiJ.busWb (a, '\0');
  2957:         XEiJ.regRn[8] = a;  //末尾の'\0'の位置
  2958:         return;
  2959:       }
  2960:       e -= Long.numberOfLeadingZeros (l) - 12;  //非正規化数の指数部を補正する
  2961:     } else if (e == 1024) {  //±Inf,NaN
  2962:       XEiJ.busWb (a++, '#');
  2963:       if (l == 0L) {  //±Inf
  2964:         XEiJ.busWb (a++, 'I');
  2965:         XEiJ.busWb (a++, 'N');
  2966:         XEiJ.busWb (a++, 'F');
  2967:       } else {  //NaN
  2968:         XEiJ.busWb (a++, 'N');
  2969:         XEiJ.busWb (a++, 'A');
  2970:         XEiJ.busWb (a++, 'N');
  2971:       }
  2972:       XEiJ.busWb (a, '\0');
  2973:       XEiJ.regRn[8] = a;  //末尾の'\0'の位置
  2974:       return;
  2975:     }
  2976:     //10進数で表現したときの指数部を求める
  2977:     //  10^e<=x<10^(e+1)となるeを求める
  2978:     e = (int) Math.floor ((double) e * 0.30102999566398119521373889472);  //log10(2)
  2979:     //10^-eを掛けて1<=x<10にする
  2980:     //  非正規化数の最小値から正規化数の最大値まで処理できなければならない
  2981:     //  10^-eを計算してからまとめて掛ける方法はxが非正規化数のとき10^-eがオーバーフローしてしまうので不可
  2982:     //    doubleは非正規化数の逆数を表現できない
  2983:     if (0 < e) {  //10<=x
  2984:       x *= FPK_TEN_M16QR[e & 15];
  2985:       if (16 <= e) {
  2986:         x *= FPK_TEN_M16QR[16 + (e >> 4 & 15)];
  2987:         if (256 <= e) {
  2988:           x *= FPK_TEN_M16QR[33];  //FPK_TEN_M16QR[32 + (e >> 8)]
  2989:         }
  2990:       }
  2991:     } else if (e < 0) {  //x<1
  2992:       x *= FPK_TEN_P16QR[-e & 15];
  2993:       if (e <= -16) {
  2994:         x *= FPK_TEN_P16QR[16 + (-e >> 4 & 15)];
  2995:         if (e <= -256) {
  2996:           x *= FPK_TEN_P16QR[33];  //FPK_TEN_P16QR[32 + (-e >> 8)]
  2997:         }
  2998:       }
  2999:     }
  3000:     //整数部2桁、小数部16桁の10進数に変換する
  3001:     //  1<=x<10なのでw[1]が先頭になるはずだが誤差で前後にずれる可能性がある
  3002:     int[] w = new int[18];
  3003:     {
  3004:       int d = (int) x;
  3005:       int t = XEiJ.FMT_BCD4[d];
  3006:       w[0] = t >> 4;
  3007:       w[1] = t      & 15;
  3008:       for (int i = 2; i < 18; i += 4) {
  3009:         //xを10000倍して整数部dを引くことで小数部を残すが、このとき情報落ちが発生して誤差が蓄積する
  3010:         //Double-Doubleの乗算の要領で10000倍を正確に行い、誤差の蓄積を回避する
  3011:         //x = (x - (double) d) * 10000.0;
  3012:         double xh = x * 0x8000001p0;
  3013:         xh += x - xh;  //xの上半分
  3014:         x = (xh - (double) d) * 10000.0 + (x - xh) * 10000.0;
  3015:         d = (int) x;
  3016:         t = XEiJ.FMT_BCD4[d];
  3017:         w[i    ] = t >> 12;
  3018:         w[i + 1] = t >>  8 & 15;
  3019:         w[i + 2] = t >>  4 & 15;
  3020:         w[i + 3] = t       & 15;
  3021:       }
  3022:     }
  3023:     //先頭の位置を確認する
  3024:     //  w[h]が先頭(0でない最初の数字)の位置
  3025:     int h = w[0] != 0 ? 0 : w[1] != 0 ? 1 : 2;
  3026:     //14+1桁目を四捨五入する
  3027:     int o = h + 14;  //w[o]は四捨五入する桁の位置。w[]の範囲内
  3028:     if (5 <= w[o]) {
  3029:       int i = o;
  3030:       while (10 <= ++w[--i]) {
  3031:         w[i] = 0;
  3032:       }
  3033:       if (i < h) {  //先頭から繰り上がった。このとき新しい先頭は1でそれ以外はすべて0
  3034:         h--;  //先頭を左にずらす
  3035:         o--;  //末尾を左にずらす
  3036:       }
  3037:     }
  3038:     //先頭の位置に応じて指数部を更新する
  3039:     //  w[h]が整数部、w[h+1..o-1]が小数部。10^eの小数点はw[h]の右側。整数部の桁数はe+1桁
  3040:     e -= h - 1;
  3041:     //末尾の位置を確認する
  3042:     //  w[o-1]が末尾(0でない最後の数字)の位置
  3043:     while (w[o - 1] == 0) {  //全体は0ではないので必ず止まる。小数点よりも左側で止まる場合があることに注意
  3044:       o--;
  3045:     }
  3046:     //指数形式にするかどうか選択して文字列に変換する
  3047:     if (0 <= e && e < len3) {  //1<=x<10^len3。指数形式にしない
  3048:       for (; 0 <= e && h < o; e--) {
  3049:         XEiJ.busWb (a++, '0' + w[h++]);  //整数部
  3050:       }
  3051:       for (; 0 <= e; e--) {
  3052:         XEiJ.busWb (a++, '0');  //整数部。末尾の位置に関係なく1の位まで書く
  3053:       }
  3054:       if (h < o) {  //小数部がある
  3055:         XEiJ.busWb (a++, '.');  //小数部があるときだけ小数点を書く
  3056:         do {
  3057:           XEiJ.busWb (a++, '0' + w[h++]);  //小数部
  3058:         } while (h < o);
  3059:       }
  3060:     } else if (-4 <= e && e < 0) {  //10^-4<=x<1。指数形式にしない
  3061:       XEiJ.busWb (a++, '0');  //整数部の0
  3062:       XEiJ.busWb (a++, '.');  //小数点
  3063:       while (++e < 0) {
  3064:         XEiJ.busWb (a++, '0');  //小数部の先頭の0の並び
  3065:       }
  3066:       do {
  3067:         XEiJ.busWb (a++, '0' + w[h++]);  //小数部
  3068:       } while (h < o);
  3069:     } else {  //x<10^-4または10^len3<=x。指数形式にする
  3070:       XEiJ.busWb (a++, '0' + w[h++]);  //整数部
  3071:       if (h < o) {  //小数部がある
  3072:         XEiJ.busWb (a++, '.');  //小数部があるときだけ小数点を書く
  3073:         do {
  3074:           XEiJ.busWb (a++, '0' + w[h++]);  //小数部
  3075:         } while (h < o);
  3076:       }
  3077:       XEiJ.busWb (a++, 'E');  //指数部の始まり
  3078:       if (0 <= e) {
  3079:         XEiJ.busWb (a++, '+');  //指数部の正符号。省略しない
  3080:       } else {
  3081:         XEiJ.busWb (a++, '-');  //指数部の負符号
  3082:         e = -e;
  3083:       }
  3084:       e = XEiJ.FMT_BCD4[e];
  3085:       XEiJ.busWb (a++, '0' + (e >> 8     ));  //指数部の100の位。0でも省略しない
  3086:       XEiJ.busWb (a++, '0' + (e >> 4 & 15));  //指数部の10の位
  3087:       XEiJ.busWb (a++, '0' + (e      & 15));  //指数部の1の位
  3088:     }
  3089:     XEiJ.busWb (a, '\0');
  3090:     XEiJ.regRn[8] = a;  //末尾の'\0'の位置
  3091:   }  //fpkDTOSSub0()
  3092: 
  3093:   //fpkECVT ()
  3094:   //  $FE24  __ECVT
  3095:   //  64bit浮動小数点数を全体の桁数を指定して文字列に変換する
  3096:   //  文字列に書くのは仮数部の数字のみ
  3097:   //  符号と小数点と指数部は文字列に書かず、小数点の位置と符号をレジスタに入れて返す
  3098:   //  桁数は255桁まで指定できるが、有効桁数は14桁まで
  3099:   //    有効桁数の次の桁で絶対値を四捨五入する
  3100:   //    15桁以上を指定しても14桁に丸められ、15桁目以降はすべて'0'になる
  3101:   //  無限大は"#INF"、非数は"#NAN"に変換する
  3102:   //    "#INF"と"#NAN"のとき小数点の位置は4になる
  3103:   //    "#INF"と"#NAN"で3桁以下のときは途中で打ち切る
  3104:   //    "#INF"と"#NAN"で5桁以上のときは5桁目以降はすべて'\0'になる
  3105:   //  バグ
  3106:   //    FLOATn.Xは"#INF"と"#NAN"で1桁~3桁のとき文字列が"$","$0","$00"になってしまう
  3107:   //      文字数が少なすぎて"#INF"や"#NAN"が入り切らないのは仕方がないが、
  3108:   //      無意味な"$00"という文字列になるのは数字ではない文字列を四捨五入しようとするバグが原因
  3109:   //      例えば3桁のときは4桁目の'F'または'N'が'5'以上なので繰り上げて上の位をインクリメントする
  3110:   //      'N'+1='O'または'A'+1='B'が'9'よりも大きいので'0'を上書きして繰り上げて上の位をインクリメントする
  3111:   //      'I'+1='J'または'N'+1='O'も'9'よりも大きいので'0'を上書きして繰り上げて上の位をインクリメントする
  3112:   //      '#'+1='$'は'9'以下なので"$00"になる
  3113:   //      X-BASICでint i2,i3:print ecvt(val("#INF"),3,i2,i3)とすると再現できる
  3114:   //    FLOATn.Xは"#NAN"と"#INF"で15桁以上のとき5桁目から14桁目までは'\0'だが15桁目以降に'0'が書き込まれる
  3115:   //      通常は5桁目の'\0'で文字列は終了していると見なされるので実害はないが気持ち悪い
  3116:   //    FLOAT2.X 2.02/2.03は0のとき小数点の位置が0になる
  3117:   //      FLOAT4.X 1.02は0のとき小数点の位置が1になる
  3118:   //      ここでは1にしている
  3119:   //  <d0d1.d:64bit浮動小数点数
  3120:   //  <d2.l:全体の桁数
  3121:   //  <a0.l:文字列バッファの先頭。末尾に'\0'を書き込むので桁数+1バイト必要
  3122:   //  >d0.l:先頭から小数点の位置までのオフセット
  3123:   //  >d1.l:符号(0=+,1=-)
  3124:   //  a0.lは変化しない
  3125:   public static void fpkECVT () throws M68kException {
  3126:     fpkECVTSub ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1]);  //64bit浮動小数点数
  3127:   }  //fpkECVT()
  3128:   public static void fpkECVTSub (long l) throws M68kException {
  3129:     int len3 = XEiJ.regRn[2];  //全体の桁数
  3130:     int a = XEiJ.regRn[8];  //文字列バッファの先頭
  3131:     if (len3 <= 0) {  //全体の桁数が0
  3132:       XEiJ.busWb (a, '\0');
  3133:       return;
  3134:     }
  3135:     int b = a + len3;  //文字列バッファの末尾+1。'\0'を書き込む位置
  3136:     //符号と指数部の処理
  3137:     //  ±0,±Inf,NaNはここで除外する
  3138:     if (0L <= l) {
  3139:       XEiJ.regRn[1] = 0;  //正符号
  3140:     } else {
  3141:       XEiJ.regRn[1] = 1;  //負符号
  3142:       l &= 0x7fffffffffffffffL;  //符号bitを消しておく
  3143:     }
  3144:     double x = Double.longBitsToDouble (l);  //絶対値
  3145:     int e = (int) (l >>> 52) - 1023;  //指数部。ゲタ0。符号bitは消してあるのでマスクは不要
  3146:     l &= 0x000fffffffffffffL;  //仮数部の小数部。正規化数のとき整数部の1が付いていないことに注意
  3147:     if (e == -1023) {  //±0,非正規化数
  3148:       if (l == 0L) {  //±0
  3149:         //指定された全体の桁数だけ'0'を並べる
  3150:         while (a < b) {
  3151:           XEiJ.busWb (a++, '0');
  3152:         }
  3153:         XEiJ.busWb (a, '\0');
  3154:         XEiJ.regRn[0] = 1;  //小数点の位置
  3155:         return;
  3156:       }
  3157:       e -= Long.numberOfLeadingZeros (l) - 12;  //非正規化数の指数部を補正する
  3158:     } else if (e == 1024) {  //±Inf,NaN
  3159:       for (int s = l != 0L ? '#' | 'N' << 8 | 'A' << 16 | 'N' << 24 : '#' | 'I' << 8 | 'N' << 16 | 'F' << 24; a < b && s != 0; s >>>= 8) {
  3160:         XEiJ.busWb (a++, s);
  3161:       }
  3162:       while (a < b) {
  3163:         XEiJ.busWb (a++, '\0');  //残りは'\0'
  3164:       }
  3165:       XEiJ.busWb (a, '\0');
  3166:       XEiJ.regRn[0] = 4;  //小数点の位置
  3167:       return;
  3168:     }
  3169:     //10進数で表現したときの指数部を求める
  3170:     //  10^e<=x<10^(e+1)となるeを求める
  3171:     e = (int) Math.floor ((double) e * 0.30102999566398119521373889472);  //log10(2)
  3172:     //10^-eを掛けて1<=x<10にする
  3173:     //  非正規化数の最小値から正規化数の最大値まで処理できなければならない
  3174:     //  10^-eを計算してからまとめて掛ける方法はxが非正規化数のとき10^-eがオーバーフローしてしまうので不可
  3175:     //    doubleは非正規化数の逆数を表現できない
  3176:     if (0 < e) {  //10<=x
  3177:       x *= FPK_TEN_M16QR[e & 15];
  3178:       if (16 <= e) {
  3179:         x *= FPK_TEN_M16QR[16 + (e >> 4 & 15)];
  3180:         if (256 <= e) {
  3181:           x *= FPK_TEN_M16QR[33];  //FPK_TEN_M16QR[32 + (e >> 8)]
  3182:         }
  3183:       }
  3184:     } else if (e < 0) {  //x<1
  3185:       x *= FPK_TEN_P16QR[-e & 15];
  3186:       if (e <= -16) {
  3187:         x *= FPK_TEN_P16QR[16 + (-e >> 4 & 15)];
  3188:         if (e <= -256) {
  3189:           x *= FPK_TEN_P16QR[33];  //FPK_TEN_P16QR[32 + (-e >> 8)]
  3190:         }
  3191:       }
  3192:     }
  3193:     //整数部2桁、小数部16桁の10進数に変換する
  3194:     //  1<=x<10なのでw[1]が先頭になるはずだが誤差で前後にずれる可能性がある
  3195:     int[] w = new int[18];
  3196:     {
  3197:       int d = (int) x;
  3198:       int t = XEiJ.FMT_BCD4[d];
  3199:       w[0] = t >> 4;
  3200:       w[1] = t      & 15;
  3201:       for (int i = 2; i < 18; i += 4) {
  3202:         //xを10000倍して整数部dを引くことで小数部を残すが、このとき情報落ちが発生して誤差が蓄積する
  3203:         //Double-Doubleの乗算の要領で10000倍を正確に行い、誤差の蓄積を回避する
  3204:         //x = (x - (double) d) * 10000.0;
  3205:         double xh = x * 0x8000001p0;
  3206:         xh += x - xh;  //xの上半分
  3207:         x = (xh - (double) d) * 10000.0 + (x - xh) * 10000.0;
  3208:         d = (int) x;
  3209:         t = XEiJ.FMT_BCD4[d];
  3210:         w[i    ] = t >> 12;
  3211:         w[i + 1] = t >>  8 & 15;
  3212:         w[i + 2] = t >>  4 & 15;
  3213:         w[i + 3] = t       & 15;
  3214:       }
  3215:     }
  3216:     //先頭の位置を確認する
  3217:     //  w[h]が先頭(0でない最初の数字)の位置
  3218:     int h = w[0] != 0 ? 0 : w[1] != 0 ? 1 : 2;
  3219:     //14+1桁目を四捨五入する
  3220:     int o = h + 14;  //w[o]は四捨五入する桁の位置。w[]の範囲内
  3221:     if (5 <= w[o]) {
  3222:       int i = o;
  3223:       while (10 <= ++w[--i]) {
  3224:         w[i] = 0;
  3225:       }
  3226:       if (i < h) {  //先頭から繰り上がった。このとき新しい先頭は1でそれ以外はすべて0
  3227:         h--;  //先頭を左にずらす
  3228:         o--;  //末尾を左にずらす
  3229:       }
  3230:     }
  3231:     //先頭の位置に応じて指数部を更新する
  3232:     //  w[h]が整数部、w[h+1..o-1]が小数部。10^eの小数点はw[h]の右側。整数部の桁数はe+1桁
  3233:     e -= h - 1;
  3234:     //先頭からlen3+1桁目が先頭から14+1桁目よりも左側にあるときその桁で改めて四捨五入する
  3235:     //  あらかじめ14+1桁目で四捨五入しておかないと、
  3236:     //  1.5の5を四捨五入しなければならないときに誤差で1.499…になったまま4を四捨五入しようとして失敗することがある
  3237:     int s = h + len3;  //w[s]は先頭からlen3+1桁目の位置。w.length<=sの場合があることに注意
  3238:     if (s < o) {
  3239:       o = s;  //w[o]は四捨五入する桁の位置。o<0の場合があることに注意
  3240:       if (0 <= o && 5 <= w[o]) {
  3241:         int i = o;
  3242:         while (10 <= ++w[--i]) {
  3243:           w[i] = 0;
  3244:         }
  3245:         if (i < h) {  //先頭から繰り上がった。このとき新しい先頭は1でそれ以外はすべて0
  3246:           h--;  //先頭を左にずらす
  3247:           o--;  //末尾を左にずらす
  3248:           e++;  //指数部を1増やす
  3249:         }
  3250:       }
  3251:     }
  3252:     //文字列に変換する
  3253:     while (a < b && h < o) {
  3254:       XEiJ.busWb (a++, '0' + w[h++]);  //有効数字
  3255:     }
  3256:     while (a < b) {
  3257:       XEiJ.busWb (a++, '0');  //残りは'0'
  3258:     }
  3259:     XEiJ.busWb (a, '\0');
  3260:     XEiJ.regRn[0] = e + 1;  //小数点の位置
  3261:   }  //fpkECVTSub0()
  3262: 
  3263:   //fpkFCVT ()
  3264:   //  $FE25  __FCVT
  3265:   //  64bit浮動小数点数を小数点以下の桁数を指定して文字列に変換する
  3266:   //  小数点の位置がpのとき[p]の左側に小数点がある
  3267:   //  全体の桁数が制限されないので指数部が大きいとき整数部が収まるサイズのバッファが必要
  3268:   //  0または1以上のとき
  3269:   //    整数部と小数点以下の指定された桁数までを小数部の0を省略せずに出力する
  3270:   //    整数部と小数点以下の指定された桁数が合わせて14桁を超えるときは15桁目が四捨五入されて15桁目以降は0になる
  3271:   //    小数点の位置は整数部の桁数に等しい
  3272:   //    print fcvt(0#,4,i2,i3),i2,i3
  3273:   //    0000     0       0
  3274:   //    print fcvt(2e+12/3#,4,i2,i3),i2,i3
  3275:   //    6666666666666700         12      0
  3276:   //               ↑
  3277:   //  1未満のとき
  3278:   //    小数点以下の桁数の範囲内を先頭の0を省略して出力する
  3279:   //    小数点以下の桁数の範囲内がすべて0のときは""になる
  3280:   //    小数点の位置は指数部+1に等しい
  3281:   //    print fcvt(0.01,3,i2,i3),i2,i3                0.010
  3282:   //    10      -1       0                              <~~
  3283:   //    print fcvt(0.001,3,i2,i3),i2,i3               0.001
  3284:   //    1       -2       0                              <<~
  3285:   //    print fcvt(0.0001,3,i2,i3),i2,i3              0.0001
  3286:   //            -3       0                              <<<
  3287:   //    print fcvt(0.00001,3,i2,i3),i2,i3             0.00001
  3288:   //            -4       0                              <<<<
  3289:   //  #INFと#NAN
  3290:   //    小数点以下の桁数の指定に関係なく4文字出力して小数点の位置4を返す
  3291:   //    print fcvt(val("#INF"),2,i2,i3),i2,i3
  3292:   //    #INF     4       0
  3293:   //    print fcvt(val("#INF"),6,i2,i3),i2,i3
  3294:   //    #INF     4       0
  3295:   //  バグ
  3296:   //    FLOAT4.X 1.02は結果が整数部が大きいとき255文字で打ち切られる
  3297:   //    FLOAT4.X 1.02はFCVT(±0)の整数部が0桁ではなく1桁になる
  3298:   //  <d0d1.d:64bit浮動小数点数
  3299:   //  <d2.l:小数点以下の桁数
  3300:   //  <a0.l:文字列バッファの先頭
  3301:   //  >d0.l:先頭から小数点の位置までのオフセット
  3302:   //  >d1.l:符号(0=+,1=-)
  3303:   public static void fpkFCVT () throws M68kException {
  3304:     fpkFCVTSub ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1]);  //64bit浮動小数点数
  3305:   }  //fpkFCVT()
  3306:   public static void fpkFCVTSub (long l) throws M68kException {
  3307:     int len2 = Math.max (0, XEiJ.regRn[2]);  //小数部の桁数
  3308:     int a = XEiJ.regRn[8];  //文字列バッファの先頭
  3309:     //符号と指数部の処理
  3310:     //  ±0,±Inf,NaNはここで除外する
  3311:     if (0L <= l) {
  3312:       XEiJ.regRn[1] = 0;  //正符号
  3313:     } else {
  3314:       XEiJ.regRn[1] = 1;  //負符号
  3315:       l &= 0x7fffffffffffffffL;  //符号bitを消しておく
  3316:     }
  3317:     double x = Double.longBitsToDouble (l);  //絶対値
  3318:     int e = (int) (l >>> 52) - 1023;  //指数部。ゲタ0。符号bitは消してあるのでマスクは不要
  3319:     l &= 0x000fffffffffffffL;  //仮数部の小数部。正規化数のとき整数部の1が付いていないことに注意
  3320:     if (e == -1023) {  //±0,非正規化数
  3321:       if (l == 0L) {  //±0
  3322:         //指定された小数点以下の桁数だけ'0'を並べる
  3323:         while (len2-- > 0) {
  3324:           XEiJ.busWb (a++, '0');
  3325:         }
  3326:         XEiJ.busWb (a, '\0');
  3327:         XEiJ.regRn[0] = 0;  //小数点の位置
  3328:         return;
  3329:       }
  3330:       e -= Long.numberOfLeadingZeros (l) - 12;  //非正規化数の指数部を補正する
  3331:     } else if (e == 1024) {  //±Inf,NaN
  3332:       XEiJ.busWb (a++, '#');
  3333:       if (l == 0L) {  //±Inf
  3334:         XEiJ.busWb (a++, 'I');
  3335:         XEiJ.busWb (a++, 'N');
  3336:         XEiJ.busWb (a++, 'F');
  3337:       } else {  //NaN
  3338:         XEiJ.busWb (a++, 'N');
  3339:         XEiJ.busWb (a++, 'A');
  3340:         XEiJ.busWb (a++, 'N');
  3341:       }
  3342:       XEiJ.busWb (a, '\0');
  3343:       XEiJ.regRn[0] = 4;  //小数点の位置
  3344:       return;
  3345:     }
  3346:     //10進数で表現したときの指数部を求める
  3347:     //  10^e<=x<10^(e+1)となるeを求める
  3348:     e = (int) Math.floor ((double) e * 0.30102999566398119521373889472);  //log10(2)
  3349:     //10^-eを掛けて1<=x<10にする
  3350:     //  非正規化数の最小値から正規化数の最大値まで処理できなければならない
  3351:     //  10^-eを計算してからまとめて掛ける方法はxが非正規化数のとき10^-eがオーバーフローしてしまうので不可
  3352:     //    doubleは非正規化数の逆数を表現できない
  3353:     if (0 < e) {  //10<=x
  3354:       x *= FPK_TEN_M16QR[e & 15];
  3355:       if (16 <= e) {
  3356:         x *= FPK_TEN_M16QR[16 + (e >> 4 & 15)];
  3357:         if (256 <= e) {
  3358:           x *= FPK_TEN_M16QR[33];  //FPK_TEN_M16QR[32 + (e >> 8)]
  3359:         }
  3360:       }
  3361:     } else if (e < 0) {  //x<1
  3362:       x *= FPK_TEN_P16QR[-e & 15];
  3363:       if (e <= -16) {
  3364:         x *= FPK_TEN_P16QR[16 + (-e >> 4 & 15)];
  3365:         if (e <= -256) {
  3366:           x *= FPK_TEN_P16QR[33];  //FPK_TEN_P16QR[32 + (-e >> 8)]
  3367:         }
  3368:       }
  3369:     }
  3370:     //整数部2桁、小数部16桁の10進数に変換する
  3371:     //  1<=x<10なのでw[1]が先頭になるはずだが誤差で前後にずれる可能性がある
  3372:     int[] w = new int[18];
  3373:     {
  3374:       int d = (int) x;
  3375:       int t = XEiJ.FMT_BCD4[d];
  3376:       w[0] = t >> 4;
  3377:       w[1] = t      & 15;
  3378:       for (int i = 2; i < 18; i += 4) {
  3379:         //xを10000倍して整数部dを引くことで小数部を残すが、このとき情報落ちが発生して誤差が蓄積する
  3380:         //Double-Doubleの乗算の要領で10000倍を正確に行い、誤差の蓄積を回避する
  3381:         //x = (x - (double) d) * 10000.0;
  3382:         double xh = x * 0x8000001p0;
  3383:         xh += x - xh;  //xの上半分
  3384:         x = (xh - (double) d) * 10000.0 + (x - xh) * 10000.0;
  3385:         d = (int) x;
  3386:         t = XEiJ.FMT_BCD4[d];
  3387:         w[i    ] = t >> 12;
  3388:         w[i + 1] = t >>  8 & 15;
  3389:         w[i + 2] = t >>  4 & 15;
  3390:         w[i + 3] = t       & 15;
  3391:       }
  3392:     }
  3393:     //先頭の位置を確認する
  3394:     //  w[h]が先頭(0でない最初の数字)の位置
  3395:     int h = w[0] != 0 ? 0 : w[1] != 0 ? 1 : 2;
  3396:     //14+1桁目を四捨五入する
  3397:     int o = h + 14;  //w[o]は四捨五入する桁の位置。w[]の範囲内
  3398:     if (5 <= w[o]) {
  3399:       int i = o;
  3400:       while (10 <= ++w[--i]) {
  3401:         w[i] = 0;
  3402:       }
  3403:       if (i < h) {  //先頭から繰り上がった。このとき新しい先頭は1でそれ以外はすべて0
  3404:         h--;  //先頭を左にずらす
  3405:         o--;  //末尾を左にずらす
  3406:       }
  3407:     }
  3408:     //先頭の位置に応じて指数部を更新する
  3409:     //  w[h]が整数部、w[h+1..o-1]が小数部。10^eの小数点はw[h]の右側。整数部の桁数はe+1桁
  3410:     e -= h - 1;
  3411:     //小数点以下len2+1桁目が先頭から14+1桁目よりも左側にあるときその桁で改めて四捨五入する
  3412:     //  あらかじめ14+1桁目で四捨五入しておかないと、
  3413:     //  1.5の5を四捨五入しなければならないときに誤差で1.499…になったまま4を四捨五入しようとして失敗することがある
  3414:     int s = h + e + 1 + len2;  //w[s]は小数点以下len2+1桁目の位置。w.length<=sの場合があることに注意
  3415:     if (s < o) {
  3416:       o = s;  //w[o]は四捨五入する桁の位置。o<0の場合があることに注意
  3417:       if (0 <= o && 5 <= w[o]) {
  3418:         int i = o;
  3419:         while (10 <= ++w[--i]) {
  3420:           w[i] = 0;
  3421:         }
  3422:         if (i < h) {  //先頭から繰り上がった。このとき新しい先頭は1でそれ以外はすべて0
  3423:           h--;  //先頭を左にずらす
  3424:           o--;  //末尾を左にずらす
  3425:           e++;  //指数部を1増やす
  3426:         }
  3427:       }
  3428:     }
  3429:     //文字列に変換する
  3430:     while (h < o) {
  3431:       XEiJ.busWb (a++, '0' + w[h++]);  //有効数字
  3432:     }
  3433:     while (h++ < s) {
  3434:       XEiJ.busWb (a++, '0');  //残りは'0'
  3435:     }
  3436:     XEiJ.busWb (a, '\0');
  3437:     XEiJ.regRn[0] = e + 1;  //小数点の位置
  3438:   }  //fpkFCVTSub0()
  3439: 
  3440:   //fpkGCVT ()
  3441:   //  $FE26  __GCVT
  3442:   //  64bit浮動小数点数を全体の桁数を指定して文字列に変換する
  3443:   //  指定された桁数で表現できないときは指数表現になる
  3444:   //  メモ
  3445:   //    print gcvt(1e-1,10)
  3446:   //    0.1
  3447:   //    print gcvt(1e-8,10)
  3448:   //    0.00000001
  3449:   //    print gcvt(1.5e-8,10)
  3450:   //    1.5E-008
  3451:   //    print gcvt(1e-9,10)
  3452:   //    1.E-009                 小数点はあるが小数部がない
  3453:   //    print gcvt(2e-1/3#,10)
  3454:   //    6.666666667E-002
  3455:   //    print gcvt(2e+0/3#,10)
  3456:   //    0.6666666667
  3457:   //    print gcvt(2e+1/3#,10)
  3458:   //    6.666666667
  3459:   //    print gcvt(2e+9/3#,10)
  3460:   //    666666666.7
  3461:   //    print gcvt(2e+10/3#,10)
  3462:   //    6666666667
  3463:   //    print gcvt(2e+11/3#,10)
  3464:   //    6.666666667E+010
  3465:   //    print gcvt(0#,4)
  3466:   //    0.
  3467:   //    print gcvt(val("#INF"),4)
  3468:   //    #INF
  3469:   //    print gcvt(val("#INF"),3)
  3470:   //    $.E+003
  3471:   //    print gcvt(val("#INF"),2)
  3472:   //    $.E+003
  3473:   //    print gcvt(val("#INF"),1)
  3474:   //    $.E+003
  3475:   //    FLOAT2.XのGCVTは小数部がなくても桁数の範囲内であれば小数点を書く
  3476:   //    桁数ちょうどのときは小数点も指数部も付かないので、整数でないことを明確にするために小数点を書いているとも言い難い
  3477:   //    ここでは#NANと#INF以外は小数部がなくても小数点を書くことにする
  3478:   //  バグ
  3479:   //    FLOAT2.X 2.02/2.03は#NANと#INFにも小数点を付ける
  3480:   //    FLOAT2.X 2.02/2.03は#NANと#INFのとき桁数が足りないと指数形式にしようとして文字列が壊れる
  3481:   //    FLOAT4.X 1.02は#NANと#INFにも小数点を付ける
  3482:   //    FLOAT4.X 1.02は桁数の少ない整数には小数点を付けて桁数ちょうどの整数には小数点も指数部も付けない
  3483:   //  <d0d1.d:64bit浮動小数点数
  3484:   //  <d2.b:全体の桁数
  3485:   //  <a0.l:文字列バッファの先頭
  3486:   //  >a0.l:末尾の'\0'の位置
  3487:   public static void fpkGCVT () throws M68kException {
  3488:     fpkGCVTSub ((long) XEiJ.regRn[0] << 32 | 0xffffffffL & XEiJ.regRn[1]);  //64bit浮動小数点数
  3489:   }  //fpkGCVT()
  3490:   public static void fpkGCVTSub (long l) throws M68kException {
  3491:     int len3 = XEiJ.regRn[2];  //全体の桁数
  3492:     int a = XEiJ.regRn[8];  //文字列バッファの先頭
  3493:     if (len3 <= 0) {  //全体の桁数が0
  3494:       XEiJ.busWb (a, '\0');
  3495:       return;
  3496:     }
  3497:     //符号と指数部の処理
  3498:     //  ±0,±Inf,NaNはここで除外する
  3499:     if (l < 0L) {
  3500:       XEiJ.busWb (a++, '-');  //負符号
  3501:       l &= 0x7fffffffffffffffL;  //符号bitを消しておく
  3502:     }
  3503:     double x = Double.longBitsToDouble (l);  //絶対値
  3504:     int e = (int) (l >>> 52) - 1023;  //指数部。ゲタ0。符号bitは消してあるのでマスクは不要
  3505:     l &= 0x000fffffffffffffL;  //仮数部の小数部。正規化数のとき整数部の1が付いていないことに注意
  3506:     if (e == -1023) {  //±0,非正規化数
  3507:       if (l == 0L) {  //±0
  3508:         XEiJ.busWb (a++, '0');  //0
  3509:         XEiJ.busWb (a++, '.');  //小数点
  3510:         XEiJ.busWb (a, '\0');
  3511:         XEiJ.regRn[8] = a;  //末尾の'\0'の位置
  3512:         return;
  3513:       }
  3514:       e -= Long.numberOfLeadingZeros (l) - 12;  //非正規化数の指数部を補正する
  3515:     } else if (e == 1024) {  //±Inf,NaN
  3516:       XEiJ.busWb (a++, '#');
  3517:       if (l == 0L) {  //±Inf
  3518:         XEiJ.busWb (a++, 'I');
  3519:         XEiJ.busWb (a++, 'N');
  3520:         XEiJ.busWb (a++, 'F');
  3521:       } else {  //NaN
  3522:         XEiJ.busWb (a++, 'N');
  3523:         XEiJ.busWb (a++, 'A');
  3524:         XEiJ.busWb (a++, 'N');
  3525:       }
  3526:       XEiJ.busWb (a, '\0');
  3527:       XEiJ.regRn[8] = a;  //末尾の'\0'の位置
  3528:       return;
  3529:     }
  3530:     //10進数で表現したときの指数部を求める
  3531:     //  10^e<=x<10^(e+1)となるeを求める
  3532:     e = (int) Math.floor ((double) e * 0.30102999566398119521373889472);  //log10(2)
  3533:     //10^-eを掛けて1<=x<10にする
  3534:     //  非正規化数の最小値から正規化数の最大値まで処理できなければならない
  3535:     //  10^-eを計算してからまとめて掛ける方法はxが非正規化数のとき10^-eがオーバーフローしてしまうので不可
  3536:     //    doubleは非正規化数の逆数を表現できない
  3537:     if (0 < e) {  //10<=x
  3538:       x *= FPK_TEN_M16QR[e & 15];
  3539:       if (16 <= e) {
  3540:         x *= FPK_TEN_M16QR[16 + (e >> 4 & 15)];
  3541:         if (256 <= e) {
  3542:           x *= FPK_TEN_M16QR[33];  //FPK_TEN_M16QR[32 + (e >> 8)]
  3543:         }
  3544:       }
  3545:     } else if (e < 0) {  //x<1
  3546:       x *= FPK_TEN_P16QR[-e & 15];
  3547:       if (e <= -16) {
  3548:         x *= FPK_TEN_P16QR[16 + (-e >> 4 & 15)];
  3549:         if (e <= -256) {
  3550:           x *= FPK_TEN_P16QR[33];  //FPK_TEN_P16QR[32 + (-e >> 8)]
  3551:         }
  3552:       }
  3553:     }
  3554:     //整数部2桁、小数部16桁の10進数に変換する
  3555:     //  1<=x<10なのでw[1]が先頭になるはずだが誤差で前後にずれる可能性がある
  3556:     int[] w = new int[18];
  3557:     {
  3558:       int d = (int) x;
  3559:       int t = XEiJ.FMT_BCD4[d];
  3560:       w[0] = t >> 4;
  3561:       w[1] = t      & 15;
  3562:       for (int i = 2; i < 18; i += 4) {
  3563:         //xを10000倍して整数部dを引くことで小数部を残すが、このとき情報落ちが発生して誤差が蓄積する
  3564:         //Double-Doubleの乗算の要領で10000倍を正確に行い、誤差の蓄積を回避する
  3565:         //x = (x - (double) d) * 10000.0;
  3566:         double xh = x * 0x8000001p0;
  3567:         xh += x - xh;  //xの上半分
  3568:         x = (xh - (double) d) * 10000.0 + (x - xh) * 10000.0;
  3569:         d = (int) x;
  3570:         t = XEiJ.FMT_BCD4[d];
  3571:         w[i    ] = t >> 12;
  3572:         w[i + 1] = t >>  8 & 15;
  3573:         w[i + 2] = t >>  4 & 15;
  3574:         w[i + 3] = t       & 15;
  3575:       }
  3576:     }
  3577:     //先頭の位置を確認する
  3578:     //  w[h]が先頭(0でない最初の数字)の位置
  3579:     int h = w[0] != 0 ? 0 : w[1] != 0 ? 1 : 2;
  3580:     //14+1桁目を四捨五入する
  3581:     int o = h + 14;  //w[o]は四捨五入する桁の位置。w[]の範囲内
  3582:     if (5 <= w[o]) {
  3583:       int i = o;
  3584:       while (10 <= ++w[--i]) {
  3585:         w[i] = 0;
  3586:       }
  3587:       if (i < h) {  //先頭から繰り上がった。このとき新しい先頭は1でそれ以外はすべて0
  3588:         h--;  //先頭を左にずらす
  3589:         o--;  //末尾を左にずらす
  3590:       }
  3591:     }
  3592:     //先頭の位置に応じて指数部を更新する
  3593:     //  w[h]が整数部、w[h+1..o-1]が小数部。10^eの小数点はw[h]の右側。整数部の桁数はe+1桁
  3594:     e -= h - 1;
  3595:     //先頭からlen3+1桁目が先頭から14+1桁目よりも左側にあるときその桁で改めて四捨五入する
  3596:     //  あらかじめ14+1桁目で四捨五入しておかないと、
  3597:     //  1.5の5を四捨五入しなければならないときに誤差で1.499…になったまま4を四捨五入しようとして失敗することがある
  3598:     int s = h + len3;  //w[s]は先頭からlen3+1桁目の位置。w.length<=sの場合があることに注意
  3599:     if (s < o) {
  3600:       o = s;  //w[o]は四捨五入する桁の位置。o<0の場合があることに注意
  3601:       if (0 <= o && 5 <= w[o]) {
  3602:         int i = o;
  3603:         while (10 <= ++w[--i]) {
  3604:           w[i] = 0;
  3605:         }
  3606:         if (i < h) {  //先頭から繰り上がった。このとき新しい先頭は1でそれ以外はすべて0
  3607:           h--;  //先頭を左にずらす
  3608:           o--;  //末尾を左にずらす
  3609:           e++;  //指数部を1増やす
  3610:         }
  3611:       }
  3612:     }
  3613:     //末尾の位置を確認する
  3614:     //  w[o-1]が末尾(0でない最後の数字)の位置
  3615:     while (w[o - 1] == 0) {  //全体は0ではないので必ず止まる。小数点よりも左側で止まる場合があることに注意
  3616:       o--;
  3617:     }
  3618:     //指数形式にするかどうか選択して文字列に変換する
  3619:     if (0 <= e && e < len3) {  //1<=x<10^len3。指数形式にしない
  3620:       for (; 0 <= e && h < o; e--) {
  3621:         XEiJ.busWb (a++, '0' + w[h++]);  //整数部
  3622:       }
  3623:       for (; 0 <= e; e--) {
  3624:         XEiJ.busWb (a++, '0');  //整数部。末尾の位置に関係なく1の位まで書く
  3625:       }
  3626:       XEiJ.busWb (a++, '.');  //小数部がなくても小数点を書く
  3627:       while (h < o) {
  3628:         XEiJ.busWb (a++, '0' + w[h++]);  //小数部
  3629:       }
  3630:     } else if (-4 <= e && e < 0) {  //10^-4<=x<1。指数形式にしない
  3631:       XEiJ.busWb (a++, '0');  //整数部の0
  3632:       XEiJ.busWb (a++, '.');  //小数点
  3633:       while (++e < 0) {
  3634:         XEiJ.busWb (a++, '0');  //小数部の先頭の0の並び
  3635:       }
  3636:       while (h < o) {
  3637:         XEiJ.busWb (a++, '0' + w[h++]);  //小数部
  3638:       }
  3639:     } else {  //x<10^-4または10^len3<=x。指数形式にする
  3640:       XEiJ.busWb (a++, '0' + w[h++]);  //整数部
  3641:       XEiJ.busWb (a++, '.');  //小数部がなくても小数点を書く
  3642:       while (h < o) {
  3643:         XEiJ.busWb (a++, '0' + w[h++]);  //小数部
  3644:       }
  3645:       XEiJ.busWb (a++, 'E');  //指数部の始まり
  3646:       if (0 <= e) {
  3647:         XEiJ.busWb (a++, '+');  //指数部の正符号。省略しない
  3648:       } else {
  3649:         XEiJ.busWb (a++, '-');  //指数部の負符号
  3650:         e = -e;
  3651:       }
  3652:       e = XEiJ.FMT_BCD4[e];
  3653:       XEiJ.busWb (a++, '0' + (e >> 8     ));  //指数部の100の位。0でも省略しない
  3654:       XEiJ.busWb (a++, '0' + (e >> 4 & 15));  //指数部の10の位
  3655:       XEiJ.busWb (a++, '0' + (e      & 15));  //指数部の1の位
  3656:     }
  3657:     XEiJ.busWb (a, '\0');
  3658:     XEiJ.regRn[8] = a;  //末尾の'\0'の位置
  3659:   }  //fpkGCVTSub0()
  3660: 
  3661:   //fpkFVAL ()
  3662:   //  $FE50  __FVAL
  3663:   //  文字列を32bit浮動小数点数に変換する
  3664:   //  __VALとほぼ同じ
  3665:   //  <a0.l:文字列の先頭
  3666:   //  >d0.s:32bit浮動小数点数
  3667:   //  >d2.l:(先頭が'&'でないとき)65535=32bit浮動小数点数をオーバーフローなしでintに変換できる,0=それ以外
  3668:   //  >d3.l:(先頭が'&'でないとき)d2.l==65535のとき32bit浮動小数点数をintに変換した値
  3669:   //  >a0.l:変換された文字列の直後('\0'とは限らない)
  3670:   //  >ccr:0=エラーなし,N|C=文法エラー,V|C=オーバーフロー
  3671:   public static void fpkFVAL () throws M68kException {
  3672:     int a = XEiJ.regRn[8];  //a0
  3673:     //先頭の空白を読み飛ばす
  3674:     int c = XEiJ.busRbs (a++);
  3675:     while (c == ' ' || c == '\t') {
  3676:       c = XEiJ.busRbs (a++);
  3677:     }
  3678:     if (c == '&') {  //&B,&O,&H
  3679:       c = XEiJ.busRbs (a++) & 0xdf;
  3680:       XEiJ.regRn[8] = a;  //&?の直後
  3681:       if (c == 'B') {
  3682:         fpkSTOB ();
  3683:         fpkLTOF ();
  3684:       } else if (c == 'O') {
  3685:         fpkSTOO ();
  3686:         fpkLTOF ();
  3687:       } else if (c == 'H') {
  3688:         fpkSTOH ();
  3689:         fpkLTOF ();
  3690:       } else {
  3691:         XEiJ.regCCR = XEiJ.REG_CCR_N | XEiJ.REG_CCR_C;  //文法エラー
  3692:       }
  3693:     } else {  //&B,&O,&H以外
  3694:       fpkSTOF ();
  3695:     }
  3696:   }  //fpkFVAL()
  3697: 
  3698:   //fpkFUSING ()
  3699:   //  $FE51  __FUSING
  3700:   //  32bit浮動小数点数をアトリビュートを指定して文字列に変換する
  3701:   //  __USINGとほぼ同じ
  3702:   //  <d0.s:32bit浮動小数点数
  3703:   //  <d2.l:整数部の桁数
  3704:   //  <d3.l:小数部の桁数
  3705:   //  <d4.l:アトリビュート
  3706:   //    bit0  左側を'*'で埋める
  3707:   //    bit1  先頭に'\\'を付ける
  3708:   //    bit2  整数部を3桁毎に','で区切る
  3709:   //    bit3  指数形式
  3710:   //    bit4  先頭に符号('+'または'-')を付ける
  3711:   //    bit5  末尾に符号('+'または'-')を付ける
  3712:   //    bit6  末尾に符号(' 'または'-')を付ける
  3713:   //  <a0.l:文字列バッファの先頭
  3714:   //  a0は変化しない
  3715:   public static void fpkFUSING () throws M68kException {
  3716:     fpkUSINGSub (Double.doubleToLongBits ((double) Float.intBitsToFloat (XEiJ.regRn[0])));  //32bit浮動小数点数
  3717:   }  //fpkFUSING()
  3718: 
  3719:   //fpkSTOF ()
  3720:   //  $FE52  __STOF
  3721:   //  文字列を32bit浮動小数点数に変換する
  3722:   //  __STODとほぼ同じ
  3723:   //  <a0.l:文字列の先頭
  3724:   //  >d0.s:32bit浮動小数点数
  3725:   //  >d2.l:65535=32bit浮動小数点数をオーバーフローなしでintに変換できる,0=それ以外
  3726:   //  >d3.l:d2.l==65535のとき32bit浮動小数点数をintに変換した値
  3727:   //  >a0.l:変換された文字列の直後('\0'とは限らない)
  3728:   //  >ccr:0=エラーなし,N|C=文法エラー,V|C=オーバーフロー
  3729:   public static void fpkSTOF () throws M68kException {
  3730:     int h = Float.floatToIntBits ((float) fpkSTODSub ());  //d0
  3731:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  3732:       h = 0x7fffffff;
  3733:     }
  3734:     XEiJ.regRn[0] = h;
  3735:   }  //fpkSTOF()
  3736: 
  3737:   //fpkFTOS ()
  3738:   //  $FE53  __FTOS
  3739:   //  32bit浮動小数点数を文字列に変換する
  3740:   //  __DTOSとほぼ同じ
  3741:   //  <d0.s:32bit浮動小数点数
  3742:   //  <a0.l:文字列バッファの先頭
  3743:   //  >a0.l:末尾の'\0'の位置
  3744:   public static void fpkFTOS () throws M68kException {
  3745:     fpkDTOSSub (Double.doubleToLongBits ((double) Float.intBitsToFloat (XEiJ.regRn[0])));  //32bit浮動小数点数
  3746:   }  //fpkFTOS()
  3747: 
  3748:   //fpkFECVT ()
  3749:   //  $FE54  __FECVT
  3750:   //  32bit浮動小数点数を全体の桁数を指定して文字列に変換する
  3751:   //  __ECVTとほぼ同じ
  3752:   //  <d0.s:32bit浮動小数点数
  3753:   //  <d2.b:全体の桁数
  3754:   //  <a0.l:文字列バッファの先頭。末尾に'\0'を書き込むので桁数+1バイト必要
  3755:   //  >d0.l:先頭から小数点の位置までのオフセット
  3756:   //  >d1.l:符号(0=+,1=-)
  3757:   //  a0.lは変化しない
  3758:   public static void fpkFECVT () throws M68kException {
  3759:     fpkECVTSub (Double.doubleToLongBits ((double) Float.intBitsToFloat (XEiJ.regRn[0])));  //32bit浮動小数点数
  3760:   }  //fpkFECVT()
  3761: 
  3762:   //fpkFFCVT ()
  3763:   //  $FE55  __FFCVT
  3764:   //  32bit浮動小数点数を小数点以下の桁数を指定して文字列に変換する
  3765:   //  __FCVTとほぼ同じ
  3766:   //  <d0.s:32bit浮動小数点数
  3767:   //  <d2.b:小数点以下の桁数
  3768:   //  <a0.l:文字列バッファの先頭
  3769:   //  >d0.l:先頭から小数点の位置までのオフセット
  3770:   //  >d1.l:符号(0=+,1=-)
  3771:   public static void fpkFFCVT () throws M68kException {
  3772:     fpkFCVTSub (Double.doubleToLongBits ((double) Float.intBitsToFloat (XEiJ.regRn[0])));  //32bit浮動小数点数
  3773:   }  //fpkFFCVT()
  3774: 
  3775:   //fpkFGCVT ()
  3776:   //  $FE56  __FGCVT
  3777:   //  32bit浮動小数点数を全体の桁数を指定して文字列に変換する
  3778:   //  __GCVTとほぼ同じ
  3779:   //  <d0.s:32bit浮動小数点数
  3780:   //  <d2.b:全体の桁数
  3781:   //  <a0.l:文字列バッファの先頭
  3782:   //  >a0.l:末尾の'\0'の位置
  3783:   public static void fpkFGCVT () throws M68kException {
  3784:     fpkGCVTSub (Double.doubleToLongBits ((double) Float.intBitsToFloat (XEiJ.regRn[0])));  //32bit浮動小数点数
  3785:   }  //fpkFGCVT()
  3786: 
  3787:   //fpkCLMUL ()
  3788:   //  $FEE0  __CLMUL
  3789:   //  32bit符号あり整数乗算
  3790:   //  <(a7).l:32bit符号あり整数。被乗数x
  3791:   //  <4(a7).l:32bit符号あり整数。乗数y
  3792:   //  >(a7).l:32bit符号あり整数。積x*y。オーバーフローのときは不定
  3793:   //  >ccr:cs=オーバーフロー。C以外は不定
  3794:   public static void fpkCLMUL () throws M68kException {
  3795:     int a7 = XEiJ.regRn[15];
  3796:     long l = (long) XEiJ.busRls (a7) * (long) XEiJ.busRls (a7 + 4);
  3797:     int h = (int) l;
  3798:     XEiJ.busWl (a7, h);  //オーバーフローのときは積の下位32bit
  3799:     XEiJ.regCCR = (long) h == l ? 0 : XEiJ.REG_CCR_C;
  3800:   }  //fpkCLMUL()
  3801: 
  3802:   //fpkCLDIV ()
  3803:   //  $FEE1  __CLDIV
  3804:   //  32bit符号あり整数除算
  3805:   //  <(a7).l:32bit符号あり整数。被除数x
  3806:   //  <4(a7).l:32bit符号あり整数。除数y
  3807:   //  >(a7).l:32bit符号あり整数。商x/y。ゼロ除算のときは不定
  3808:   //  >ccr:cs=ゼロ除算。C以外は不定
  3809:   public static void fpkCLDIV () throws M68kException {
  3810:     int a7 = XEiJ.regRn[15];
  3811:     int h = XEiJ.busRls (a7 + 4);
  3812:     if (h == 0) {
  3813:       //(a7).lは変化しない
  3814:       XEiJ.regCCR = XEiJ.REG_CCR_C;
  3815:     } else {
  3816:       XEiJ.busWl (a7, XEiJ.busRls (a7) / h);
  3817:       XEiJ.regCCR = 0;
  3818:     }
  3819:   }  //fpkCLDIV()
  3820: 
  3821:   //fpkCLMOD ()
  3822:   //  $FEE2  __CLMOD
  3823:   //  32bit符号あり整数剰余算
  3824:   //  <(a7).l:32bit符号あり整数。被除数x
  3825:   //  <4(a7).l:32bit符号あり整数。除数y
  3826:   //  >(a7).l:32bit符号あり整数。余りx%y。ゼロ除算のときは不定
  3827:   //  >ccr:cs=ゼロ除算。C以外は不定
  3828:   public static void fpkCLMOD () throws M68kException {
  3829:     int a7 = XEiJ.regRn[15];
  3830:     int h = XEiJ.busRls (a7 + 4);
  3831:     if (h == 0) {
  3832:       //(a7).lは変化しない
  3833:       XEiJ.regCCR = XEiJ.REG_CCR_C;
  3834:     } else {
  3835:       XEiJ.busWl (a7, XEiJ.busRls (a7) % h);
  3836:       XEiJ.regCCR = 0;
  3837:     }
  3838:   }  //fpkCLMOD()
  3839: 
  3840:   //fpkCUMUL ()
  3841:   //  $FEE3  __CUMUL
  3842:   //  32bit符号なし整数乗算
  3843:   //  <(a7).l:32bit符号なし整数。被乗数x
  3844:   //  <4(a7).l:32bit符号なし整数。乗数y
  3845:   //  >(a7).l:32bit符号なし整数。積x*y。オーバーフローのときは不定
  3846:   //  >ccr:cs=オーバーフロー。C以外は不定
  3847:   public static void fpkCUMUL () throws M68kException {
  3848:     int a7 = XEiJ.regRn[15];
  3849:     long l = (0xffffffffL & XEiJ.busRls (a7)) * (0xffffffffL & XEiJ.busRls (a7 + 4));
  3850:     int h = (int) l;
  3851:     XEiJ.busWl (a7, h);
  3852:     XEiJ.regCCR = (0xffffffffL & h) == l ? 0 : XEiJ.REG_CCR_C;
  3853:   }  //fpkCUMUL()
  3854: 
  3855:   //fpkCUDIV ()
  3856:   //  $FEE4  __CUDIV
  3857:   //  32bit符号なし整数除算
  3858:   //  <(a7).l:32bit符号なし整数。被除数x
  3859:   //  <4(a7).l:32bit符号なし整数。除数y
  3860:   //  >(a7).l:32bit符号なし整数。商x/y。ゼロ除算のときは不定
  3861:   //  >ccr:cs=ゼロ除算。C以外は不定
  3862:   public static void fpkCUDIV () throws M68kException {
  3863:     int a7 = XEiJ.regRn[15];
  3864:     int h = XEiJ.busRls (a7 + 4);
  3865:     if (h == 0) {
  3866:       //(a7).lは変化しない
  3867:       XEiJ.regCCR = XEiJ.REG_CCR_C;
  3868:     } else {
  3869:       XEiJ.busWl (a7, (int) ((0xffffffffL & XEiJ.busRls (a7)) / (0xffffffffL & h)));
  3870:       XEiJ.regCCR = 0;
  3871:     }
  3872:   }  //fpkCUDIV()
  3873: 
  3874:   //fpkCUMOD ()
  3875:   //  $FEE5  __CUMOD
  3876:   //  32bit符号なし整数剰余算
  3877:   //  <(a7).l:32bit符号なし整数。被除数x
  3878:   //  <4(a7).l:32bit符号なし整数。除数y
  3879:   //  >(a7).l:32bit符号なし整数。余りx%y。ゼロ除算のときは不定
  3880:   //  >ccr:cs=ゼロ除算。C以外は不定
  3881:   public static void fpkCUMOD () throws M68kException {
  3882:     int a7 = XEiJ.regRn[15];
  3883:     int h = XEiJ.busRls (a7 + 4);
  3884:     if (h == 0) {
  3885:       //(a7).lは変化しない
  3886:       XEiJ.regCCR = XEiJ.REG_CCR_C;
  3887:     } else {
  3888:       XEiJ.busWl (a7, (int) ((0xffffffffL & XEiJ.busRls (a7)) % (0xffffffffL & h)));
  3889:       XEiJ.regCCR = 0;
  3890:     }
  3891:   }  //fpkCUMOD()
  3892: 
  3893:   //fpkCLTOD ()
  3894:   //  $FEE6  __CLTOD
  3895:   //  32bit符号あり整数を64bit浮動小数点数に変換する
  3896:   //  <(a7).l:32bit符号あり整数。x
  3897:   //  >(a7).d:64bit浮動小数点数。(double)x
  3898:   public static void fpkCLTOD () throws M68kException {
  3899:     //int→double→[long]→[int,int]
  3900:     int a7 = XEiJ.regRn[15];
  3901:     long l = Double.doubleToLongBits ((double) XEiJ.busRls (a7));
  3902:     XEiJ.busWl (a7, (int) (l >>> 32));
  3903:     XEiJ.busWl (a7 + 4, (int) l);
  3904:   }  //fpkCLTOD()
  3905: 
  3906:   //fpkCDTOL ()
  3907:   //  $FEE7  __CDTOL
  3908:   //  64bit浮動小数点数を32bit符号あり整数に変換する
  3909:   //  <(a7).d:64bit浮動小数点数。x
  3910:   //  >(a7).l:32bit符号あり整数。(int)x
  3911:   //  >ccr:cs=オーバーフロー。C以外は不定
  3912:   public static void fpkCDTOL () throws M68kException {
  3913:     //[int,int]→[long]→double→int
  3914:     int a7 = XEiJ.regRn[15];
  3915:     double d = Double.longBitsToDouble ((long) XEiJ.busRls (a7) << 32 | 0xffffffffL & XEiJ.busRls (a7 + 4));
  3916:     XEiJ.busWl (a7, (int) d);  //オーバーフローのときは最小値または最大値
  3917:     XEiJ.regCCR = (double) Integer.MIN_VALUE - 1.0 < d && d < (double) Integer.MAX_VALUE + 1.0 ? 0 : XEiJ.REG_CCR_C;  //NaN,±Infはエラー
  3918:   }  //fpkCDTOL()
  3919: 
  3920:   //fpkCLTOF ()
  3921:   //  $FEE8  __CLTOF
  3922:   //  32bit符号あり整数を32bit浮動小数点数に変換する
  3923:   //  <(a7).l:32bit符号あり整数。x
  3924:   //  >(a7).s:32bit浮動小数点数。(float)x
  3925:   public static void fpkCLTOF () throws M68kException {
  3926:     //int→float→[int]
  3927:     int a7 = XEiJ.regRn[15];
  3928:     XEiJ.busWl (a7, Float.floatToIntBits ((float) XEiJ.busRls (a7)));
  3929:   }  //fpkCLTOF()
  3930: 
  3931:   //fpkCFTOL ()
  3932:   //  $FEE9  __CFTOL
  3933:   //  32bit浮動小数点数を32bit符号あり整数に変換する
  3934:   //  <(a7).s:32bit浮動小数点数。x
  3935:   //  >(a7).l:32bit符号あり整数。(int)x
  3936:   //  >ccr:cs=オーバーフロー。C以外は不定
  3937:   public static void fpkCFTOL () throws M68kException {
  3938:     //[int]→float→int
  3939:     int a7 = XEiJ.regRn[15];
  3940:     float f = Float.intBitsToFloat (XEiJ.busRls (a7));
  3941:     XEiJ.busWl (a7, (int) f);
  3942:     XEiJ.regCCR = (float) Integer.MIN_VALUE - 1.0F < f && f < (float) Integer.MAX_VALUE + 1.0F ? 0 : XEiJ.REG_CCR_C;  //NaN,±Infはエラー
  3943:   }  //fpkCFTOL()
  3944: 
  3945:   //fpkCFTOD ()
  3946:   //  $FEEA  __CFTOD
  3947:   //  32bit浮動小数点数を64bit浮動小数点数に変換する
  3948:   //  <(a7).s:32bit浮動小数点数。x
  3949:   //  >(a7).d:64bit浮動小数点数。(double)x
  3950:   public static void fpkCFTOD () throws M68kException {
  3951:     //[int]→float→double→[long]→[int,int]
  3952:     int a7 = XEiJ.regRn[15];
  3953:     long l = Double.doubleToLongBits ((double) Float.intBitsToFloat (XEiJ.busRls (a7)));
  3954:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
  3955:       l = 0x7fffffffffffffffL;
  3956:     }
  3957:     XEiJ.busWl (a7, (int) (l >>> 32));
  3958:     XEiJ.busWl (a7 + 4, (int) l);
  3959:   }  //fpkCFTOD()
  3960: 
  3961:   //fpkCDTOF ()
  3962:   //  $FEEB  __CDTOF
  3963:   //  64bit浮動小数点数を32bit浮動小数点数に変換する
  3964:   //  <(a7).d:64bit浮動小数点数。x
  3965:   //  >(a7).s:32bit浮動小数点数。(float)x
  3966:   //  >ccr:cs=オーバーフロー。C以外は不定
  3967:   public static void fpkCDTOF () throws M68kException {
  3968:     //[int,int]→[long]→double→float→[int]
  3969:     int a7 = XEiJ.regRn[15];
  3970:     double d = Double.longBitsToDouble ((long) XEiJ.busRls (a7) << 32 | 0xffffffffL & XEiJ.busRls (a7 + 4));
  3971:     int h = Float.floatToIntBits ((float) d);
  3972:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  3973:       h = 0x7fffffff;
  3974:     }
  3975:     XEiJ.busWl (a7, h);
  3976:     XEiJ.regCCR = (Double.isNaN (d) || Double.isInfinite (d) ||
  3977:            Math.abs (d) < (double) Float.MAX_VALUE + 0.5 * (double) Math.ulp (Float.MAX_VALUE) ? 0 : XEiJ.REG_CCR_C);  //アンダーフローはエラーなし
  3978:   }  //fpkCDTOF()
  3979: 
  3980:   //fpkCDCMP ()
  3981:   //  $FEEC  __CDCMP
  3982:   //  64bit浮動小数点数の比較
  3983:   //  x<=>y
  3984:   //  <(a7).d:64bit浮動小数点数。x
  3985:   //  <8(a7).d:64bit浮動小数点数。y
  3986:   //  >ccr:lt=x<y,eq=x==y,gt=x>y
  3987:   public static void fpkCDCMP () throws M68kException {
  3988:     //([int,int]→[long]→double)<=>([int,int]→[long]→double)
  3989:     int a7 = XEiJ.regRn[15];
  3990:     double xd = Double.longBitsToDouble ((long) XEiJ.busRls (a7) << 32 | 0xffffffffL & XEiJ.busRls (a7 + 4));
  3991:     double yd = Double.longBitsToDouble ((long) XEiJ.busRls (a7 + 8) << 32 | 0xffffffffL & XEiJ.busRls (a7 + 12));
  3992:     XEiJ.regCCR = xd < yd ? XEiJ.REG_CCR_N | XEiJ.REG_CCR_C : xd == yd ? XEiJ.REG_CCR_Z : 0;  //どちらかがNaNのときは0
  3993:   }  //fpkCDCMP()
  3994: 
  3995:   //fpkCDADD ()
  3996:   //  $FEED  __CDADD
  3997:   //  64bit浮動小数点数の加算
  3998:   //  <(a7).d:64bit浮動小数点数。被加算数x
  3999:   //  <8(a7).d:64bit浮動小数点数。加算数y
  4000:   //  >(a7).d:64bit浮動小数点数。和x+y
  4001:   //  >ccr:0=エラーなし,C=アンダーフロー,V|C=オーバーフロー
  4002:   public static void fpkCDADD () throws M68kException {
  4003:     //([int,int]→[long]→double)+([int,int]→[long]→double)→[long]→[int,int]
  4004:     int a7 = XEiJ.regRn[15];
  4005:     double xd = Double.longBitsToDouble ((long) XEiJ.busRls (a7) << 32 | 0xffffffffL & XEiJ.busRls (a7 + 4));
  4006:     double yd = Double.longBitsToDouble ((long) XEiJ.busRls (a7 + 8) << 32 | 0xffffffffL & XEiJ.busRls (a7 + 12));
  4007:     double zd = xd + yd;
  4008:     long l = Double.doubleToLongBits (zd);
  4009:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
  4010:       l = 0x7fffffffffffffffL;
  4011:     }
  4012:     XEiJ.busWl (a7, (int) (l >>> 32));
  4013:     XEiJ.busWl (a7 + 4, (int) l);
  4014:     XEiJ.regCCR = (Double.isNaN (xd) || Double.isNaN (yd) ? 0 :  //引数がNaN
  4015:            Double.isNaN (zd) ? XEiJ.REG_CCR_C :  //引数がNaNでないのに結果がNaNのときはエラー。(+Inf)+(-Inf)=NaN
  4016:            Double.isInfinite (xd) || Double.isInfinite (yd) ? 0 :  //引数が±Inf
  4017:            Double.isInfinite (zd) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C :  //引数が±Infでないのに結果が±Infのときはオーバーフロー
  4018:            0);
  4019:   }  //fpkCDADD()
  4020: 
  4021:   //fpkCDSUB ()
  4022:   //  $FEEE  __CDSUB
  4023:   //  64bit浮動小数点数の減算
  4024:   //  <(a7).d:64bit浮動小数点数。被減算数x
  4025:   //  <8(a7).d:64bit浮動小数点数。減算数y
  4026:   //  >(a7).d:64bit浮動小数点数。差x-y
  4027:   //  >ccr:cs=エラー,vs=オーバーフロー
  4028:   public static void fpkCDSUB () throws M68kException {
  4029:     //([int,int]→[long]→double)-([int,int]→[long]→double)→[long]→[int,int]
  4030:     int a7 = XEiJ.regRn[15];
  4031:     double xd = Double.longBitsToDouble ((long) XEiJ.busRls (a7) << 32 | 0xffffffffL & XEiJ.busRls (a7 + 4));
  4032:     double yd = Double.longBitsToDouble ((long) XEiJ.busRls (a7 + 8) << 32 | 0xffffffffL & XEiJ.busRls (a7 + 12));
  4033:     double zd = xd - yd;
  4034:     long l = Double.doubleToLongBits (zd);
  4035:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
  4036:       l = 0x7fffffffffffffffL;
  4037:     }
  4038:     XEiJ.busWl (a7, (int) (l >>> 32));
  4039:     XEiJ.busWl (a7 + 4, (int) l);
  4040:     XEiJ.regCCR = (Double.isNaN (xd) || Double.isNaN (yd) ? 0 :  //引数がNaN
  4041:            Double.isNaN (zd) ? XEiJ.REG_CCR_C :  //引数がNaNでないのに結果がNaNのときはエラー。(+Inf)-(+Inf)=NaN
  4042:            Double.isInfinite (xd) || Double.isInfinite (yd) ? 0 :  //引数が±Inf
  4043:            Double.isInfinite (zd) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C :  //引数が±Infでないのに結果が±Infのときはオーバーフロー
  4044:            0);
  4045:   }  //fpkCDSUB()
  4046: 
  4047:   //fpkCDMUL ()
  4048:   //  $FEEF  __CDMUL
  4049:   //  64bit浮動小数点数の乗算
  4050:   //  <(a7).d:64bit浮動小数点数。被乗数x
  4051:   //  <8(a7).d:64bit浮動小数点数。乗数y
  4052:   //  >(a7).d:64bit浮動小数点数。積x*y
  4053:   //  >ccr:cs=エラー,vs=オーバーフロー
  4054:   public static void fpkCDMUL () throws M68kException {
  4055:     //([int,int]→[long]→double)*([int,int]→[long]→double)→[long]→[int,int]
  4056:     int a7 = XEiJ.regRn[15];
  4057:     double xd = Double.longBitsToDouble ((long) XEiJ.busRls (a7) << 32 | 0xffffffffL & XEiJ.busRls (a7 + 4));
  4058:     double yd = Double.longBitsToDouble ((long) XEiJ.busRls (a7 + 8) << 32 | 0xffffffffL & XEiJ.busRls (a7 + 12));
  4059:     double zd = xd * yd;
  4060:     long l = Double.doubleToLongBits (zd);
  4061:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
  4062:       l = 0x7fffffffffffffffL;
  4063:     }
  4064:     XEiJ.busWl (a7, (int) (l >>> 32));
  4065:     XEiJ.busWl (a7 + 4, (int) l);
  4066:     XEiJ.regCCR = (Double.isNaN (xd) || Double.isNaN (yd) ? 0 :  //引数がNaN
  4067:            Double.isNaN (zd) ? XEiJ.REG_CCR_C :  //引数がNaNでないのに結果がNaNのときはエラー。(±0)*(±Inf)=NaN
  4068:            Double.isInfinite (xd) || Double.isInfinite (yd) ? 0 :  //引数が±Inf
  4069:            Double.isInfinite (zd) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C :  //引数が±Infでないのに結果が±Infのときはオーバーフロー
  4070:            0);
  4071:   }  //fpkCDMUL()
  4072: 
  4073:   //fpkCDDIV ()
  4074:   //  $FEF0  __CDDIV
  4075:   //  64bit浮動小数点数の除算
  4076:   //  <(a7).d:64bit浮動小数点数。被除数x
  4077:   //  <8(a7).d:64bit浮動小数点数。除数y
  4078:   //  >(a7).d:64bit浮動小数点数。商x/y。ゼロ除算のときは不定
  4079:   //  >ccr:cs=エラー,eq=ゼロ除算,vs=オーバーフロー
  4080:   public static void fpkCDDIV () throws M68kException {
  4081:     //([int,int]→[long]→double)/([int,int]→[long]→double)→[long]→[int,int]
  4082:     int a7 = XEiJ.regRn[15];
  4083:     double xd = Double.longBitsToDouble ((long) XEiJ.busRls (a7) << 32 | 0xffffffffL & XEiJ.busRls (a7 + 4));
  4084:     double yd = Double.longBitsToDouble ((long) XEiJ.busRls (a7 + 8) << 32 | 0xffffffffL & XEiJ.busRls (a7 + 12));
  4085:     double zd = xd / yd;
  4086:     long l = Double.doubleToLongBits (zd);
  4087:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
  4088:       l = 0x7fffffffffffffffL;
  4089:     }
  4090:     XEiJ.busWl (a7, (int) (l >>> 32));
  4091:     XEiJ.busWl (a7 + 4, (int) l);
  4092:     XEiJ.regCCR = (Double.isNaN (xd) || Double.isNaN (yd) ? 0 :  //引数がNaN
  4093:            Double.isNaN (zd) ? XEiJ.REG_CCR_C :  //引数がNaNでないのに結果がNaNのときはエラー。(±0)/(±0)=NaN
  4094:            Double.isInfinite (xd) || Double.isInfinite (yd) ? 0 :  //引数が±Inf。(±Inf)/(±0)=(±Inf)
  4095:            yd == 0.0 ? XEiJ.REG_CCR_Z | XEiJ.REG_CCR_C :  //除数が±0のときはゼロ除算
  4096:            Double.isInfinite (zd) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C :  //引数が±Infでないのに結果が±Infのときはオーバーフロー
  4097:            0);
  4098:   }  //fpkCDDIV()
  4099: 
  4100:   //fpkCDMOD ()
  4101:   //  $FEF1  __CDMOD
  4102:   //  64bit浮動小数点数の剰余算
  4103:   //  <(a7).d:64bit浮動小数点数。被除数x
  4104:   //  <8(a7).d:64bit浮動小数点数。除数y
  4105:   //  >(a7).d:64bit浮動小数点数。余りx%y。ゼロ除算のときは不定
  4106:   //  >ccr:cs=エラー,eq=ゼロ除算
  4107:   public static void fpkCDMOD () throws M68kException {
  4108:     //([int,int]→[long]→double)%([int,int]→[long]→double)→[long]→[int,int]
  4109:     int a7 = XEiJ.regRn[15];
  4110:     double xd = Double.longBitsToDouble ((long) XEiJ.busRls (a7) << 32 | 0xffffffffL & XEiJ.busRls (a7 + 4));
  4111:     double yd = Double.longBitsToDouble ((long) XEiJ.busRls (a7 + 8) << 32 | 0xffffffffL & XEiJ.busRls (a7 + 12));
  4112:     double zd = xd % yd;
  4113:     long l = Double.doubleToLongBits (zd);
  4114:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
  4115:       l = 0x7fffffffffffffffL;
  4116:     }
  4117:     XEiJ.busWl (a7, (int) (l >>> 32));
  4118:     XEiJ.busWl (a7 + 4, (int) l);
  4119:     XEiJ.regCCR = (Double.isNaN (xd) || Double.isNaN (yd) ? 0 :  //引数がNaN
  4120:            yd == 0.0 ? XEiJ.REG_CCR_Z | XEiJ.REG_CCR_C :  //除数が0のときはゼロ除算。(±Inf)%(±0)=NaN, x%(±0)=(±Inf)
  4121:            Double.isNaN (zd) ? XEiJ.REG_CCR_C :  //引数がNaNでないのに結果がNaNのときはエラー。(±Inf)%y=NaN
  4122:            Double.isInfinite (xd) || Double.isInfinite (yd) ? 0 :  //引数が±Inf
  4123:            Double.isInfinite (zd) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C :  //引数が±Infでないのに結果が±Infのときはオーバーフロー
  4124:            0);
  4125:   }  //fpkCDMOD()
  4126: 
  4127:   //fpkCFCMP ()
  4128:   //  $FEF2  __CFCMP
  4129:   //  32bit浮動小数点数の比較
  4130:   //  x<=>y
  4131:   //  <(a7).s:32bit浮動小数点数。x
  4132:   //  <4(a7).s:32bit浮動小数点数。y
  4133:   //  >ccr:lt=x<y,eq=x==y,gt=x>y
  4134:   public static void fpkCFCMP () throws M68kException {
  4135:     //([int]→float)<=>([int]→float)
  4136:     int a7 = XEiJ.regRn[15];
  4137:     float xf = Float.intBitsToFloat (XEiJ.busRls (a7));
  4138:     float yf = Float.intBitsToFloat (XEiJ.busRls (a7 + 4));
  4139:     XEiJ.regCCR = xf < yf ? XEiJ.REG_CCR_N | XEiJ.REG_CCR_C : xf == yf ? XEiJ.REG_CCR_Z : 0;  //どちらかがNaNのときは0
  4140:   }  //fpkCFCMP()
  4141: 
  4142:   //fpkCFADD ()
  4143:   //  $FEF3  __CFADD
  4144:   //  32bit浮動小数点数の加算
  4145:   //  <(a7).s:32bit浮動小数点数。被加算数x
  4146:   //  <4(a7).s:32bit浮動小数点数。加算数y
  4147:   //  >(a7).s:32bit浮動小数点数。和x+y
  4148:   //  >ccr:cs=エラー,vs=オーバーフロー
  4149:   public static void fpkCFADD () throws M68kException {
  4150:     //([int]→float)+([int]→float)→[int]
  4151:     int a7 = XEiJ.regRn[15];
  4152:     float xf = Float.intBitsToFloat (XEiJ.busRls (a7));
  4153:     float yf = Float.intBitsToFloat (XEiJ.busRls (a7 + 4));
  4154:     float zf = xf + yf;
  4155:     int h = Float.floatToIntBits (zf);
  4156:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  4157:       h = 0x7fffffff;
  4158:     }
  4159:     XEiJ.busWl (a7, h);
  4160:     XEiJ.regCCR = (Float.isNaN (xf) || Float.isNaN (yf) ? 0 :  //引数がNaN
  4161:            Float.isNaN (zf) ? XEiJ.REG_CCR_C :  //引数がNaNでないのに結果がNaNのときはエラー。(+Inf)+(-Inf)=NaN
  4162:            Float.isInfinite (xf) || Float.isInfinite (yf) ? 0 :  //引数が±Inf
  4163:            Float.isInfinite (zf) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C :  //引数が±Infでないのに結果が±Infのときはオーバーフロー
  4164:            0);
  4165:   }  //fpkCFADD()
  4166: 
  4167:   //fpkCFSUB ()
  4168:   //  $FEF4  __CFSUB
  4169:   //  32bit浮動小数点数の減算
  4170:   //  <(a7).s:32bit浮動小数点数。被減算数x
  4171:   //  <4(a7).s:32bit浮動小数点数。減算数y
  4172:   //  >(a7).s:32bit浮動小数点数。差x-y
  4173:   //  >ccr:cs=エラー,vs=オーバーフロー
  4174:   public static void fpkCFSUB () throws M68kException {
  4175:     //([int]→float)-([int]→float)→[int]
  4176:     int a7 = XEiJ.regRn[15];
  4177:     float xf = Float.intBitsToFloat (XEiJ.busRls (a7));
  4178:     float yf = Float.intBitsToFloat (XEiJ.busRls (a7 + 4));
  4179:     float zf = xf - yf;
  4180:     int h = Float.floatToIntBits (zf);
  4181:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  4182:       h = 0x7fffffff;
  4183:     }
  4184:     XEiJ.busWl (a7, h);
  4185:     XEiJ.regCCR = (Float.isNaN (xf) || Float.isNaN (yf) ? 0 :  //引数がNaN
  4186:            Float.isNaN (zf) ? XEiJ.REG_CCR_C :  //引数がNaNでないのに結果がNaNのときはエラー。(+Inf)-(+Inf)=NaN
  4187:            Float.isInfinite (xf) || Float.isInfinite (yf) ? 0 :  //引数が±Inf
  4188:            Float.isInfinite (zf) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C :  //引数が±Infでないのに結果が±Infのときはオーバーフロー
  4189:            0);
  4190:   }  //fpkCFSUB()
  4191: 
  4192:   //fpkCFMUL ()
  4193:   //  $FEF5  __CFMUL
  4194:   //  32bit浮動小数点数の乗算
  4195:   //  <(a7).s:32bit浮動小数点数。被乗数x
  4196:   //  <4(a7).s:32bit浮動小数点数。乗数y
  4197:   //  >(a7).s:32bit浮動小数点数。積x*y
  4198:   //  >ccr:0=エラーなし,C=アンダーフロー,V|C=オーバーフロー
  4199:   public static void fpkCFMUL () throws M68kException {
  4200:     //([int]→float)*([int]→float)→[int]
  4201:     int a7 = XEiJ.regRn[15];
  4202:     float xf = Float.intBitsToFloat (XEiJ.busRls (a7));
  4203:     float yf = Float.intBitsToFloat (XEiJ.busRls (a7 + 4));
  4204:     float zf = xf * yf;
  4205:     int h = Float.floatToIntBits (zf);
  4206:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  4207:       h = 0x7fffffff;
  4208:     }
  4209:     XEiJ.busWl (a7, h);
  4210:     XEiJ.regCCR = (Float.isNaN (xf) || Float.isNaN (yf) ? 0 :  //引数がNaN
  4211:            Float.isNaN (zf) ? XEiJ.REG_CCR_C :  //引数がNaNでないのに結果がNaNのときはエラー。(±0)*(±Inf)=NaN
  4212:            Float.isInfinite (xf) || Float.isInfinite (yf) ? 0 :  //引数が±Inf
  4213:            Float.isInfinite (zf) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C :  //引数が±Infでないのに結果が±Infのときはオーバーフロー
  4214:            0);
  4215:   }  //fpkCFMUL()
  4216: 
  4217:   //fpkCFDIV ()
  4218:   //  $FEF6  __CFDIV
  4219:   //  32bit浮動小数点数の除算
  4220:   //  <(a7).s:32bit浮動小数点数。被除数x
  4221:   //  <4(a7).s:32bit浮動小数点数。除数y
  4222:   //  >(a7).s:32bit浮動小数点数。商x/y。ゼロ除算のときは不定
  4223:   //  >ccr:cs=エラー,eq=ゼロ除算,vs=オーバーフロー
  4224:   public static void fpkCFDIV () throws M68kException {
  4225:     //([int]→float)/([int]→float)→[int]
  4226:     int a7 = XEiJ.regRn[15];
  4227:     float xf = Float.intBitsToFloat (XEiJ.busRls (a7));
  4228:     float yf = Float.intBitsToFloat (XEiJ.busRls (a7 + 4));
  4229:     float zf = xf / yf;
  4230:     int h = Float.floatToIntBits (zf);
  4231:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  4232:       h = 0x7fffffff;
  4233:     }
  4234:     XEiJ.busWl (a7, h);
  4235:     XEiJ.regCCR = (Float.isNaN (xf) || Float.isNaN (yf) ? 0 :  //引数がNaN
  4236:            Float.isNaN (zf) ? XEiJ.REG_CCR_C :  //引数がNaNでないのに結果がNaNのときはエラー。(±0)/(±0)=NaN
  4237:            Float.isInfinite (xf) || Float.isInfinite (yf) ? 0 :  //引数が±Inf。(±Inf)/(±0)=(±Inf)
  4238:            yf == 0.0F ? XEiJ.REG_CCR_Z | XEiJ.REG_CCR_C :  //除数が±0のときはゼロ除算
  4239:            Float.isInfinite (zf) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C :  //引数が±Infでないのに結果が±Infのときはオーバーフロー
  4240:            0);
  4241:   }  //fpkCFDIV()
  4242: 
  4243:   //fpkCFMOD ()
  4244:   //  $FEF7  __CFMOD
  4245:   //  32bit浮動小数点数の剰余算
  4246:   //  <(a7).s:32bit浮動小数点数。被除数x
  4247:   //  <4(a7).s:32bit浮動小数点数。除数y
  4248:   //  >(a7).s:32bit浮動小数点数。余りx%y。ゼロ除算のときは不定
  4249:   //  >ccr:cs=エラー,eq=ゼロ除算
  4250:   public static void fpkCFMOD () throws M68kException {
  4251:     //([int]→float)%([int]→float)→[int]
  4252:     int a7 = XEiJ.regRn[15];
  4253:     float xf = Float.intBitsToFloat (XEiJ.busRls (a7));
  4254:     float yf = Float.intBitsToFloat (XEiJ.busRls (a7 + 4));
  4255:     float zf = xf % yf;
  4256:     int h = Float.floatToIntBits (zf);
  4257:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  4258:       h = 0x7fffffff;
  4259:     }
  4260:     XEiJ.busWl (a7, h);
  4261:     XEiJ.regCCR = (Float.isNaN (xf) || Float.isNaN (yf) ? 0 :  //引数がNaN
  4262:            yf == 0.0F ? XEiJ.REG_CCR_Z | XEiJ.REG_CCR_C :  //除数が0のときはゼロ除算。(±Inf)%(±0)=NaN, x%(±0)=(±Inf)
  4263:            Float.isNaN (zf) ? XEiJ.REG_CCR_C :  //引数がNaNでないのに結果がNaNのときはエラー。(±Inf)%y=NaN
  4264:            Float.isInfinite (xf) || Float.isInfinite (yf) ? 0 :  //引数が±Inf
  4265:            Float.isInfinite (zf) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C :  //引数が±Infでないのに結果が±Infのときはオーバーフロー
  4266:            0);
  4267:   }  //fpkCFMOD()
  4268: 
  4269:   //fpkCDTST ()
  4270:   //  $FEF8  __CDTST
  4271:   //  64bit浮動小数点数と0の比較
  4272:   //  x<=>0
  4273:   //  <(a7).d:64bit浮動小数点数。x
  4274:   //  >ccr:lt=x<0,eq=x==0,gt=x>0
  4275:   public static void fpkCDTST () throws M68kException {
  4276:     if (true) {
  4277:       int a7 = XEiJ.regRn[15];
  4278:       long l = (long) XEiJ.busRls (a7) << 32 | 0xffffffffL & XEiJ.busRls (a7 + 4);
  4279:       XEiJ.regCCR = l << 1 == 0L ? XEiJ.REG_CCR_Z : 0L <= l ? 0 : XEiJ.REG_CCR_N;  //NaNのときは0
  4280:     } else {
  4281:       //[int,int]→[long]→double
  4282:       int a7 = XEiJ.regRn[15];
  4283:       double d = Double.longBitsToDouble ((long) XEiJ.busRls (a7) << 32 | 0xffffffffL & XEiJ.busRls (a7 + 4));
  4284:       XEiJ.regCCR = d < 0.0 ? XEiJ.REG_CCR_N : d == 0.0 ? XEiJ.REG_CCR_Z : 0;  //NaNのときは0
  4285:     }
  4286:   }  //fpkCDTST()
  4287: 
  4288:   //fpkCFTST ()
  4289:   //  $FEF9  __CFTST
  4290:   //  32bit浮動小数点数と0の比較
  4291:   //  x<=>0
  4292:   //  <(a7).s:32bit浮動小数点数。x
  4293:   //  >ccr:lt=x<0,eq=x==0,gt=x>0
  4294:   public static void fpkCFTST () throws M68kException {
  4295:     //[int]→float
  4296:     if (true) {
  4297:       int h = XEiJ.busRls (XEiJ.regRn[15]);
  4298:       XEiJ.regCCR = h << 1 == 0 ? XEiJ.REG_CCR_Z : 0 <= h ? 0 : XEiJ.REG_CCR_N;  //NaNのときは0
  4299:     } else {
  4300:       //([int]→float)<=>0
  4301:       float f = Float.intBitsToFloat (XEiJ.busRls (XEiJ.regRn[15]));
  4302:       XEiJ.regCCR = f < 0.0F ? XEiJ.REG_CCR_N : f == 0.0F ? XEiJ.REG_CCR_Z : 0;  //NaNのときは0
  4303:     }
  4304:   }  //fpkCFTST()
  4305: 
  4306:   //fpkCDINC ()
  4307:   //  $FEFA  __CDINC
  4308:   //  64bit浮動小数点数に1を加える
  4309:   //  <(a7).d:64bit浮動小数点数。x
  4310:   //  >(a7).d:64bit浮動小数点数。x+1
  4311:   public static void fpkCDINC () throws M68kException {
  4312:     //([int,int]→[long]→double)+1→[long]→[int,int]
  4313:     int a7 = XEiJ.regRn[15];
  4314:     double xd = Double.longBitsToDouble ((long) XEiJ.busRls (a7) << 32 | 0xffffffffL & XEiJ.busRls (a7 + 4));
  4315:     double zd = xd + 1.0;
  4316:     long l = Double.doubleToLongBits (zd);
  4317:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
  4318:       l = 0x7fffffffffffffffL;
  4319:     }
  4320:     XEiJ.busWl (a7, (int) (l >>> 32));
  4321:     XEiJ.busWl (a7 + 4, (int) l);
  4322:     XEiJ.regCCR = Double.isInfinite (zd) && !Double.isInfinite (xd) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C : 0;  //結果が±Infだが引数が±Infでないときはオーバーフロー
  4323:   }  //fpkCDINC()
  4324: 
  4325:   //fpkCFINC ()
  4326:   //  $FEFB  __CFINC
  4327:   //  32bit浮動小数点数に1を加える
  4328:   //  <(a7).s:32bit浮動小数点数。x
  4329:   //  >(a7).s:32bit浮動小数点数。x+1
  4330:   public static void fpkCFINC () throws M68kException {
  4331:     //([int]→float)+1→[int]
  4332:     int a7 = XEiJ.regRn[15];
  4333:     float xf = Float.intBitsToFloat (XEiJ.busRls (a7));
  4334:     float zf = xf + 1.0F;
  4335:     int h = Float.floatToIntBits (zf);
  4336:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  4337:       h = 0x7fffffff;
  4338:     }
  4339:     XEiJ.busWl (a7, h);
  4340:     XEiJ.regCCR = Double.isInfinite (zf) && !Float.isInfinite (xf) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C : 0;  //結果が±Infだが引数が±Infでないときはオーバーフロー
  4341:   }  //fpkCFINC()
  4342: 
  4343:   //fpkCDDEC ()
  4344:   //  $FEFC  __CDDEC
  4345:   //  64bit浮動小数点数から1を引く
  4346:   //  <(a7).d:64bit浮動小数点数。x
  4347:   //  >(a7).d:64bit浮動小数点数。x-1
  4348:   public static void fpkCDDEC () throws M68kException {
  4349:     //([int,int]→[long]→double)-1→[long]→[int,int]
  4350:     int a7 = XEiJ.regRn[15];
  4351:     double xd = Double.longBitsToDouble ((long) XEiJ.busRls (a7) << 32 | 0xffffffffL & XEiJ.busRls (a7 + 4));
  4352:     double zd = xd - 1.0;
  4353:     long l = Double.doubleToLongBits (zd);
  4354:     if (FPK_FPCP_NAN && l == 0x7ff8000000000000L) {
  4355:       l = 0x7fffffffffffffffL;
  4356:     }
  4357:     XEiJ.busWl (a7, (int) (l >>> 32));
  4358:     XEiJ.busWl (a7 + 4, (int) l);
  4359:     XEiJ.regCCR = Double.isInfinite (zd) && !Double.isInfinite (xd) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C : 0;  //結果が±Infだが引数が±Infでないときはオーバーフロー
  4360:   }  //fpkCDDEC()
  4361: 
  4362:   //fpkCFDEC ()
  4363:   //  $FEFD  __CFDEC
  4364:   //  32bit浮動小数点数から1を引く
  4365:   //  <(a7).s:32bit浮動小数点数。x
  4366:   //  >(a7).s:32bit浮動小数点数。x-1
  4367:   public static void fpkCFDEC () throws M68kException {
  4368:     //([int]→float)-1→[int]
  4369:     int a7 = XEiJ.regRn[15];
  4370:     float xf = Float.intBitsToFloat (XEiJ.busRls (a7));
  4371:     float zf = xf - 1.0F;
  4372:     int h = Float.floatToIntBits (zf);
  4373:     if (FPK_FPCP_NAN && h == 0x7fc00000) {
  4374:       h = 0x7fffffff;
  4375:     }
  4376:     XEiJ.busWl (a7, h);
  4377:     XEiJ.regCCR = Double.isInfinite (zf) && !Float.isInfinite (xf) ? XEiJ.REG_CCR_V | XEiJ.REG_CCR_C : 0;  //結果が±Infだが引数が±Infでないときはオーバーフロー
  4378:   }  //fpkCFDEC()
  4379: 
  4380: }  //class FEFunction
  4381: 
  4382: 
  4383: