OSDN Git Service

HeavyOSECPUMainの各変数名を適切なものへ変更。
[heavyosecpu/HeavyOSECPU.git] / jitcx86a.c
index f77f3b0..d460b0d 100644 (file)
-#include "osecpu.h"
-#include "jitc.h"
-
-#if (JITC_ARCNUM == 0x0001)
-//
-// for x86-32bit
-//
-int jitCompGetImm32(const unsigned char *src)
-{
-       return (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
-}
-
-int jitCompGetLabelNum(struct JitCompWork *w, const unsigned char *src)
-{
-       int i = jitCompGetImm32(src);
-       if (i < 0 || i >= w->maxLabels) {
-               w->err = JITC_ERR_LABELNUM;
-               i = 0;
-       }
-       return i;
-}
-
-void jitCompPutModRM_Disp_BaseEBP(struct JitCompWork *w, int disp, int opReg)
-{
-       // EBPをベースとするアドレスオペランドとレジスタオペランドを出力する
-       disp -= jitCompA0001_EBP128;
-       if (-128 <= disp && disp <= 127) {
-               // [EBP + Disp08]
-               jitCompPutByte1(w->dst, IA32_MOD_R_M(IA32_OP_MOD_INDEX_AND_DISP_BYTE, opReg, IA32_REG5_EBP));
-               jitCompPutByte1(w->dst, disp & 0xff);
-       } else {
-               // [EBP + Disp32]
-               jitCompPutByte1(w->dst, IA32_MOD_R_M(IA32_OP_MOD_INDEX_AND_DISP_FULL, opReg, IA32_REG5_EBP));
-               jitCompPutImm32(w->dst, disp);
-       }
-       return;
-}
-
-void jitCompPutOp_MOV_EBPDisp_GReg(struct JitCompWork *w, int disp, int reg32)
-{
-       // MOV([EBP + disp] <- reg32);
-       // MOV Ev, Gv
-       // [1000 100 1] [mod reg r/m]
-       jitCompPutByte1(w->dst, 0x89);
-       jitCompPutModRM_Disp_BaseEBP(w, disp, reg32);
-       return;
-}
-
-void jitCompPutOp_MOV_GReg_EBPDisp(struct JitCompWork *w, int reg32, int disp)
-{
-       // MOV (reg32 <- [EBP + disp])
-       // MOV Gv, Ev
-       // [1000 101 1] [mod reg r/m]
-       jitCompPutByte1(w->dst, 0x8b);
-       jitCompPutModRM_Disp_BaseEBP(w, disp, reg32);
-       return;
-}
-
-void jitCompA0001_movEaxRxx(struct JitCompWork *w, int rxx)
-{
-#if (jitCompA0001_USE_R3F_IMM32 != 0)
-       if (rxx == 0x3f) {
-               jitCompPutByte1(w->dst, 0xb8); /* MOV(EAX, ?); */
-               jitCompPutImm32(w->dst, w->r3f);
-               return;
-       }
-#endif
-       if (rxx >= 0x40 || rxx < 0){
-               w->err = JITC_ERR_REGNUM;
-       }
-       jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG0_EAX, rxx * 4);
-       return;
-}
-
-void jitCompA0001_movRxxEax(struct JitCompWork *w, int rxx)
-{
-       if (rxx >= 0x40 || rxx < 0){
-               w->err = JITC_ERR_REGNUM;
-       }
-       jitCompPutOp_MOV_EBPDisp_GReg(w, rxx * 4, IA32_REG0_EAX);
-       return;
-}
-
-void jitCompA0001_fixPrefix(struct JitCompWork *w)
-{
-       if (w->prefix != 0) {
-               if (w->dst - w->dst0 > 127){
-                       w->err = JITC_ERR_REGNUM;
-               }
-               w->dst0[-1] = (unsigned char)((w->dst - w->dst0) & 0xff);
-       }
-       return;
-}
-
-void jitCompA0001_checkCompPtr(struct JitCompWork *w, int p0, int p1)
-{
-       if (p0 >= 0x3f || p0 < 0){
-               w->err = JITC_ERR_PREGNUM;
-       }
-       if (p1 >= 0x3f || p1 < 0){
-               w->err = JITC_ERR_PREGNUM;
-       }
-       /* 比較可能可能なのかのチェックのコードを出力 */   /* 未完成 */
-       return;
-}
-
-void jitCompA000_loadRegCacheAll(struct JitCompWork *w)
-{
-       //保存されたレジスタキャッシュをメモリからロード
-       jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG3_EBX, 4 * 0); /* EBX = R00; */
-       jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG1_ECX, 4 * 1); /* ECX = R01; */
-       jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG2_EDX, 4 * 2); /* EDX = R02; */
-       return;
-}
-
-void jitCompA000_storeRegCacheAll(struct JitCompWork *w)
-{
-       //レジスタキャッシュをメモリに退避
-       jitCompPutOp_MOV_EBPDisp_GReg(w, 0 * 4, IA32_REG3_EBX); /* R00 = EBX; */
-       jitCompPutOp_MOV_EBPDisp_GReg(w, 1 * 4, IA32_REG1_ECX); /* R01 = ECX; */
-       jitCompPutOp_MOV_EBPDisp_GReg(w, 2 * 4, IA32_REG2_EDX); /* R02 = EDX; */
-       return;
-}
-
-void jitCompA000_loadRegCacheEcx(struct JitCompWork *w)
-{
-       jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG1_ECX, 1 * 4); /* ECX = R01; */
-       return;
-}
-
-void jitCompA000_storeRegCacheEcx(struct JitCompWork *w)
-{
-       jitCompPutOp_MOV_EBPDisp_GReg(w, 1 * 4, IA32_REG1_ECX); /* R01 = ECX; */
-       return;
-}
-
-void jitCompA000_loadRegCacheEdx(struct JitCompWork *w)
-{
-       jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG2_EDX, 2 * 4); /* EDX = R02; */
-       return;
-}
-
-void jitCompA000_storeRegCacheEdx(struct JitCompWork *w)
-{
-       jitCompPutOp_MOV_EBPDisp_GReg(w, 2 * 4, IA32_REG2_EDX); /* R02 = EDX; */
-       return;
-}
-
-int jitCompA000_selectRegCache(int rxx, int reg)
-{
-       // OSECPUレジスタ番号をIA32レジスタ番号へ変換
-       // 対応するキャッシュレジスタがない場合regが返る
-       switch (rxx) {
-               case 0:
-                       reg = IA32_REG3_EBX;
-                       break;
-               case 1:
-                       reg = IA32_REG1_ECX;
-                       break;
-               case 2:
-                       reg = IA32_REG2_EDX;
-                       break;
-       }
-       return reg;
-}
-
-void jitCompA000_loadPRegCacheAll(struct JitCompWork *w)
-{
-       jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG6_ESI, PRegOffset(0x01) + 0); /* ESI = P01; */
-       jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG7_EDI, PRegOffset(0x02) + 0); /* EDI = P02; */
-       return;
-}
-
-void jitCompA000_storePRegCacheAll(struct JitCompWork *w)
-{
-       jitCompPutOp_MOV_EBPDisp_GReg(w, PRegOffset(0x01) + 0, IA32_REG6_ESI); /* P01 = ESI; */
-       jitCompPutOp_MOV_EBPDisp_GReg(w, PRegOffset(0x02) + 0, IA32_REG7_EDI); /* P02 = EDI; */
-       return;
-}
-
-int jitCompA000_selectPRegCache(int pxx, int reg)
-{
-       //      if (pxx == 0) reg = 5; /* EBP */
-       switch (pxx) {
-               case 1:
-                       //ESI
-                       reg = 6;
-                       break;
-                       
-               case 2:
-                       //EDI
-                       reg = 7;
-                       break;
-       }
-       return reg;
-}
-
-int jitCompA000_convTyp(int t)
-{
-       // 指定されたタイプのデータ幅を返す。
-       // unsigned なら奇数(1bit目がOn)
-       // retv = 1     : VPtr
-       // retv = 2 or 3: BYTE ( 8,  4,  2,  1 bit)
-       // retv = 4 or 5: WORD (16, 12 bit)
-       // retv = 6 or 7: DWORD(32, 20, 24, 28 bit)
-       // -1はエラー
-       int r = -1;
-       
-       if (1 <= t && t <= 7){
-               // 1 - 7はそのままでOK
-               r = t;
-       } else if (8 <= t && t <= 13){
-               r = 2 | (t & 1);
-       } else if (14 <= t && t <= 15){
-               r = 4 | (t & 1);
-       } else if (16 <= t && t <= 21){
-               r = 6 | (t & 1);
-       }
-       return r;
-}
-
-int jitCompA000_dataWidth(int t)
-{
-    // 指定されたタイプのビット数を返す
-       int r = -1;
-       if (t == 0x0001) r = 256;
-       t >>= 1;
-       if (t == 0x0002 / 2) r = 8;
-       if (t == 0x0004 / 2) r = 16;
-       if (t == 0x0006 / 2) r = 32;
-       if (t == 0x0008 / 2) r = 4;
-       if (t == 0x000a / 2) r = 2;
-       if (t == 0x000c / 2) r = 1;
-       if (t == 0x000e / 2) r = 12;
-       if (t == 0x0010 / 2) r = 20;
-       if (t == 0x0012 / 2) r = 24;
-       if (t == 0x0014 / 2) r = 28;
-       return r;
-}
-
-unsigned char *errfnc;
-
-void jitCompA0001_checkType0(struct JitCompWork *w, int pxx, int typ, int ac)
-{
-       if (typ <= 0) { w->err = JITC_ERR_BADTYPE; }
-       if (typ > 0x7f) { w->err = JITC_ERR_INTERNAL; }
-       jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG0_EAX, PRegOffset(pxx) + 4); /* MOV(EAX, [EBP+?]); */  /* typ */
-       jitCompPutByte3(w->dst, 0x83, 0xf8, typ & 0x7f);        /* CMP(EAX, ?); */
-       jitCompPutByte2(w->dst, 0x0f, 0x85); /* JNE */
-       jitCompPutImm32(w->dst, errfnc - (w->dst + 4));
-       return;
-}
-
-void jitCompA0001_checkType(struct JitCompWork *w, int pxx, int typ, int ac)
-{
-       // data用.
-       // 将来的にはaliveやアクセス権チェックも入れる
-       jitCompA0001_checkType0(w, pxx, typ, ac);
-       return;
-}
-
-void jitCompA0001_checkLimit(struct JitCompWork *w, int reg, int pxx)
-{
-       jitCompPutByte1(w->dst, 0x3b);  /* CMP(reg, [EBP+?]); */
-       jitCompPutModRM_Disp_BaseEBP(w, PRegOffset(pxx) + 8, reg);      /* p0 */
-       jitCompPutByte2(w->dst, 0x0f, 0x82); /* JB */
-       jitCompPutImm32(w->dst, errfnc - (w->dst + 4));
-       jitCompPutByte1(w->dst, 0x3b);  /* CMP(reg, [EBP+?]); */
-       jitCompPutModRM_Disp_BaseEBP(w, PRegOffset(pxx) + 12, reg);     /* p1 */
-       jitCompPutByte2(w->dst, 0x0f, 0x83); /* JAE */
-       jitCompPutImm32(w->dst, errfnc - (w->dst + 4));
-       return;
-}
-
-#endif
+#include "osecpu.h"\r
+#include "jitc.h"\r
+\r
+#if (JITC_ARCNUM == 0x0001)\r
+//\r
+// for x86-32bit\r
+//\r
+int jitCompGetImm32(const unsigned char *src)\r
+{\r
+       return (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];\r
+}\r
+\r
+int jitCompGetLabelNum(struct JitCompWork *w, const unsigned char *src)\r
+{\r
+       int i = jitCompGetImm32(src);\r
+       if (i < 0 || i >= w->maxLabels) {\r
+               w->err = JITC_ERR_LABELNUM;\r
+               i = 0;\r
+       }\r
+       return i;\r
+}\r
+\r
+void jitCompPutModRM_Disp_BaseEBP(struct JitCompWork *w, int disp, int opReg)\r
+{\r
+       // EBPをベースとするアドレスオペランドとレジスタオペランドを出力する\r
+       disp -= jitCompA0001_EBP128;\r
+       if (-128 <= disp && disp <= 127) {\r
+               // [EBP + Disp08]\r
+               jitCompPutByte1(w->dst, IA32_MOD_R_M(IA32_OP_MOD_INDEX_AND_DISP_BYTE, opReg, IA32_REG5_EBP));\r
+               jitCompPutByte1(w->dst, disp & 0xff);\r
+       } else {\r
+               // [EBP + Disp32]\r
+               jitCompPutByte1(w->dst, IA32_MOD_R_M(IA32_OP_MOD_INDEX_AND_DISP_FULL, opReg, IA32_REG5_EBP));\r
+               jitCompPutImm32(w->dst, disp);\r
+       }\r
+       return;\r
+}\r
+\r
+void jitCompPutOp_MOV_EBPDisp_GReg(struct JitCompWork *w, int disp, int reg32)\r
+{\r
+       // MOV([EBP + disp] <- reg32);\r
+       // MOV Ev, Gv\r
+       // [1000 100 1] [mod reg r/m]\r
+       jitCompPutByte1(w->dst, 0x89);\r
+       jitCompPutModRM_Disp_BaseEBP(w, disp, reg32);\r
+       return;\r
+}\r
+\r
+void jitCompPutOp_MOV_GReg_EBPDisp(struct JitCompWork *w, int reg32, int disp)\r
+{\r
+       // MOV (reg32 <- [EBP + disp])\r
+       // MOV Gv, Ev\r
+       // [1000 101 1] [mod reg r/m]\r
+       jitCompPutByte1(w->dst, 0x8b);\r
+       jitCompPutModRM_Disp_BaseEBP(w, disp, reg32);\r
+       return;\r
+}\r
+\r
+void jitCompA0001_movEaxRxx(struct JitCompWork *w, int rxx)\r
+{\r
+#if (jitCompA0001_USE_R3F_IMM32 != 0)\r
+       if (rxx == 0x3f) {\r
+               jitCompPutByte1(w->dst, 0xb8); /* MOV(EAX, ?); */\r
+               jitCompPutImm32(w->dst, w->r3f);\r
+               return;\r
+       }\r
+#endif\r
+       if (rxx >= 0x40 || rxx < 0){\r
+               w->err = JITC_ERR_REGNUM;\r
+       }\r
+       jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG0_EAX, rxx * 4);\r
+       return;\r
+}\r
+\r
+void jitCompA0001_movRxxEax(struct JitCompWork *w, int rxx)\r
+{\r
+       if (rxx >= 0x40 || rxx < 0){\r
+               w->err = JITC_ERR_REGNUM;\r
+       }\r
+       jitCompPutOp_MOV_EBPDisp_GReg(w, rxx * 4, IA32_REG0_EAX);\r
+       return;\r
+}\r
+\r
+void jitCompA0001_fixPrefix(struct JitCompWork *w)\r
+{\r
+       if (w->prefix != 0) {\r
+               if (w->dst - w->dst0 > 127){\r
+                       w->err = JITC_ERR_REGNUM;\r
+               }\r
+               w->dst0[-1] = (unsigned char)((w->dst - w->dst0) & 0xff);\r
+       }\r
+       return;\r
+}\r
+\r
+void jitCompA0001_checkCompPtr(struct JitCompWork *w, int p0, int p1)\r
+{\r
+       if (p0 >= 0x3f || p0 < 0){\r
+               w->err = JITC_ERR_PREGNUM;\r
+       }\r
+       if (p1 >= 0x3f || p1 < 0){\r
+               w->err = JITC_ERR_PREGNUM;\r
+       }\r
+       /* 比較可能可能なのかのチェックのコードを出力 */   /* 未完成 */\r
+       return;\r
+}\r
+\r
+void jitCompA000_loadRegCacheAll(struct JitCompWork *w)\r
+{\r
+       //保存されたレジスタキャッシュをメモリからロード\r
+       jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG3_EBX, 4 * 0); /* EBX = R00; */\r
+       jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG1_ECX, 4 * 1); /* ECX = R01; */\r
+       jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG2_EDX, 4 * 2); /* EDX = R02; */\r
+       return;\r
+}\r
+\r
+void jitCompA000_storeRegCacheAll(struct JitCompWork *w)\r
+{\r
+       //レジスタキャッシュをメモリに退避\r
+       jitCompPutOp_MOV_EBPDisp_GReg(w, 0 * 4, IA32_REG3_EBX); /* R00 = EBX; */\r
+       jitCompPutOp_MOV_EBPDisp_GReg(w, 1 * 4, IA32_REG1_ECX); /* R01 = ECX; */\r
+       jitCompPutOp_MOV_EBPDisp_GReg(w, 2 * 4, IA32_REG2_EDX); /* R02 = EDX; */\r
+       return;\r
+}\r
+\r
+void jitCompA000_loadRegCacheEcx(struct JitCompWork *w)\r
+{\r
+       jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG1_ECX, 1 * 4); /* ECX = R01; */\r
+       return;\r
+}\r
+\r
+void jitCompA000_storeRegCacheEcx(struct JitCompWork *w)\r
+{\r
+       jitCompPutOp_MOV_EBPDisp_GReg(w, 1 * 4, IA32_REG1_ECX); /* R01 = ECX; */\r
+       return;\r
+}\r
+\r
+void jitCompA000_loadRegCacheEdx(struct JitCompWork *w)\r
+{\r
+       jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG2_EDX, 2 * 4); /* EDX = R02; */\r
+       return;\r
+}\r
+\r
+void jitCompA000_storeRegCacheEdx(struct JitCompWork *w)\r
+{\r
+       jitCompPutOp_MOV_EBPDisp_GReg(w, 2 * 4, IA32_REG2_EDX); /* R02 = EDX; */\r
+       return;\r
+}\r
+\r
+int jitCompA000_selectRegCache(int rxx, int reg)\r
+{\r
+       // OSECPUレジスタ番号をIA32レジスタ番号へ変換\r
+       // 対応するキャッシュレジスタがない場合regが返る\r
+       switch (rxx) {\r
+               case 0:\r
+                       reg = IA32_REG3_EBX;\r
+                       break;\r
+               case 1:\r
+                       reg = IA32_REG1_ECX;\r
+                       break;\r
+               case 2:\r
+                       reg = IA32_REG2_EDX;\r
+                       break;\r
+       }\r
+       return reg;\r
+}\r
+\r
+void jitCompA000_loadPRegCacheAll(struct JitCompWork *w)\r
+{\r
+       jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG6_ESI, PRegOffset(0x01) + 0); /* ESI = P01; */\r
+       jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG7_EDI, PRegOffset(0x02) + 0); /* EDI = P02; */\r
+       return;\r
+}\r
+\r
+void jitCompA000_storePRegCacheAll(struct JitCompWork *w)\r
+{\r
+       jitCompPutOp_MOV_EBPDisp_GReg(w, PRegOffset(0x01) + 0, IA32_REG6_ESI); /* P01 = ESI; */\r
+       jitCompPutOp_MOV_EBPDisp_GReg(w, PRegOffset(0x02) + 0, IA32_REG7_EDI); /* P02 = EDI; */\r
+       return;\r
+}\r
+\r
+int jitCompA000_selectPRegCache(int pxx, int reg)\r
+{\r
+       //      if (pxx == 0) reg = 5; /* EBP */\r
+       switch (pxx) {\r
+               case 1:\r
+                       //ESI\r
+                       reg = 6;\r
+                       break;\r
+                       \r
+               case 2:\r
+                       //EDI\r
+                       reg = 7;\r
+                       break;\r
+       }\r
+       return reg;\r
+}\r
+\r
+int jitCompA000_convTyp(int t)\r
+{\r
+       // 指定されたタイプのデータ幅を返す。\r
+       // unsigned なら奇数(1bit目がOn)\r
+       // retv = 1     : VPtr\r
+       // retv = 2 or 3: BYTE ( 8,  4,  2,  1 bit)\r
+       // retv = 4 or 5: WORD (16, 12 bit)\r
+       // retv = 6 or 7: DWORD(32, 20, 24, 28 bit)\r
+       // -1はエラー\r
+       int r = -1;\r
+       \r
+       if (1 <= t && t <= 7){\r
+               // 1 - 7はそのままでOK\r
+               r = t;\r
+       } else if (8 <= t && t <= 13){\r
+               r = 2 | (t & 1);\r
+       } else if (14 <= t && t <= 15){\r
+               r = 4 | (t & 1);\r
+       } else if (16 <= t && t <= 21){\r
+               r = 6 | (t & 1);\r
+       }\r
+       return r;\r
+}\r
+\r
+int jitCompA000_dataWidth(int t)\r
+{\r
+    // 指定されたタイプのビット数を返す\r
+       int r = -1;\r
+       if (t == 0x0001) r = 256;\r
+       t >>= 1;\r
+       if (t == 0x0002 / 2) r = 8;\r
+       if (t == 0x0004 / 2) r = 16;\r
+       if (t == 0x0006 / 2) r = 32;\r
+       if (t == 0x0008 / 2) r = 4;\r
+       if (t == 0x000a / 2) r = 2;\r
+       if (t == 0x000c / 2) r = 1;\r
+       if (t == 0x000e / 2) r = 12;\r
+       if (t == 0x0010 / 2) r = 20;\r
+       if (t == 0x0012 / 2) r = 24;\r
+       if (t == 0x0014 / 2) r = 28;\r
+       return r;\r
+}\r
+\r
+unsigned char *errfnc;\r
+\r
+void jitCompA0001_checkType0(struct JitCompWork *w, int pxx, int typ, int ac)\r
+{\r
+       if (typ <= 0) {\r
+               w->err = JITC_ERR_BADTYPE;\r
+       }\r
+       if (typ > 0x7f) {\r
+               w->err = JITC_ERR_INTERNAL;\r
+       }\r
+       jitCompPutOp_MOV_GReg_EBPDisp(w, IA32_REG0_EAX, PRegOffset(pxx) + 4); /* MOV(EAX, pReg[pxx].typ); */\r
+       jitCompPutByte3(w->dst, 0x83, 0xf8, typ & 0x7f);        /* CMP(EAX, typ); */\r
+       jitCompPutByte2(w->dst, 0x0f, 0x85); /* JNE */\r
+       jitCompPutImm32(w->dst, errfnc - (w->dst + 4));\r
+       return;\r
+}\r
+\r
+void jitCompA0001_checkType(struct JitCompWork *w, int pxx, int typ, int ac)\r
+{\r
+       // data用.\r
+       // 将来的にはaliveやアクセス権チェックも入れる\r
+       jitCompA0001_checkType0(w, pxx, typ, ac);\r
+       return;\r
+}\r
+\r
+void jitCompA0001_checkLimit(struct JitCompWork *w, int reg, int pxx)\r
+{\r
+       jitCompPutByte1(w->dst, 0x3b);  /* CMP(reg, [EBP+?]); */\r
+       jitCompPutModRM_Disp_BaseEBP(w, PRegOffset(pxx) + 8, reg);      /* p0 */\r
+       jitCompPutByte2(w->dst, 0x0f, 0x82); /* JB */\r
+       jitCompPutImm32(w->dst, errfnc - (w->dst + 4));\r
+       jitCompPutByte1(w->dst, 0x3b);  /* CMP(reg, [EBP+?]); */\r
+       jitCompPutModRM_Disp_BaseEBP(w, PRegOffset(pxx) + 12, reg);     /* p1 */\r
+       jitCompPutByte2(w->dst, 0x0f, 0x83); /* JAE */\r
+       jitCompPutImm32(w->dst, errfnc - (w->dst + 4));\r
+       return;\r
+}\r
+\r
+#endif\r