0001 //
0002 // Binds the silly sauce from parser.c to HolyC. AIWNIOS is built so when
0003 //  you write a backend,HolyC will use it too,that way you dont have to re-port
0004 //  your backend again when you port to another arch
0005 //
0006 #ifdef IMPORT_AIWNIOS_SYMS
0007 import U0 __HC_SetAOTRelocBeforeRIP(U8 *,I64); //See aiwn.h(TAKES number of bytes before current RIP the symbol is located at)
0008 import U8 *__HC_CmpCtrlDel(U8 *);
0009 import U8 *__HC_ICAdd_RawBytes(U8*,U8*,I64);
0010 import U8 *__HC_ICAdd_GetVargsPtr(U8*);
0011 import U8 *__HC_ICAdd_ToF64(U8 *);
0012 import U8 *__HC_ICAdd_ToI64(U8 *);
0013 import U0 __HC_ICSetLine(U8*,I64);
0014 import U8 *__HC_ICAdd_Max_I64(U8 *);
0015 import U8 *__HC_ICAdd_Min_I64(U8 *);
0016 import U8 *__HC_ICAdd_Max_U64(U8 *);
0017 import U8 *__HC_ICAdd_Min_U64(U8 *);
0018 import U8 *__HC_ICAdd_Max_F64(U8 *);
0019 import U8 *__HC_ICAdd_Min_F64(U8 *);
0020 import U8 *__HC_ICAdd_Typecast(U8 *,I64,I64);
0021 import U8 *__HC_ICAdd_SubCall(U8 *,U8 *);
0022 import U8 *__HC_ICAdd_SubProlog(U8 *);
0023 import U8 *__HC_ICAdd_SubRet(U8 *);
0024 import U8 *__HC_ICAdd_BoundedSwitch(U8*,U8*,U8*);
0025 import U8 *__HC_ICAdd_UnboundedSwitch(U8 *,U8 *);
0026 import U8 *__HC_ICAdd_PreInc(U8 *,I64);
0027 import U8 *__HC_ICAdd_Call(U8*,I64,I64 rt,I64 ptrs);
0028 import U8 *__HC_ICAdd_F64(U8*,F64);
0029 import U8 *__HC_ICAdd_I64(U8*,I64);
0030 import U8 * __HC_ICAdd_PreDec(U8*,I64);
0031 import U8 * __HC_ICAdd_PostDec(U8*,I64);
0032 import U8 * __HC_ICAdd_PostInc(U8*,I64);
0033 import U8 * __HC_ICAdd_Pow(U8 *);
0034 import U8 * __HC_ICAdd_Lock(U8 *);
0035 import U8 * __HC_ICAdd_Eq(U8*);
0036 import U8 * __HC_ICAdd_Div(U8*);
0037 import U8 * __HC_ICAdd_Sub(U8*);
0038 import U8 * __HC_ICAdd_Mul(U8*);
0039 import U8 * __HC_ICAdd_Add(U8*);
0040 import U8 * __HC_ICAdd_Deref(U8*,I64 rt,I64 ptrs);
0041 import U8 * __HC_ICAdd_Comma(U8*);
0042 import U0 __HC_ICSetLock(U8*);
0043 import U8 * __HC_ICAdd_Addr(U8*);
0044 import U8 * __HC_ICAdd_Xor(U8*);
0045 import U8 * __HC_ICAdd_Mod(U8*);
0046 import U8 * __HC_ICAdd_Or(U8*);
0047 import U8 * __HC_ICAdd_Lt(U8*);
0048 import U8 * __HC_ICAdd_Gt(U8*);
0049 import U8 * __HC_ICAdd_Le(U8*);
0050 import U8 * __HC_ICAdd_Ge(U8*);
0051 import U8 * __HC_ICAdd_LNot(U8*);
0052 import U8 * __HC_ICAdd_BNot(U8*);
0053 import U8 * __HC_ICAdd_AndAnd(U8*);
0054 import U8 * __HC_ICAdd_And(U8*);
0055 import U8 * __HC_ICAdd_OrOr(U8*);
0056 import U8 * __HC_ICAdd_XorXor(U8*);
0057 import U8 * __HC_ICAdd_Ne(U8*);
0058 import U8 * __HC_ICAdd_EqEq(U8*);
0059 import U8 * __HC_ICAdd_Lsh(U8*);
0060 import U8 * __HC_ICAdd_Rsh(U8*);
0061 import U8 * __HC_ICAdd_AddEq(U8*);
0062 import U8 * __HC_ICAdd_SubEq(U8*);
0063 import U8 * __HC_ICAdd_MulEq(U8*);
0064 import U8 * __HC_ICAdd_DivEq(U8*);
0065 import U8 * __HC_ICAdd_LshEq(U8*);
0066 import U8 * __HC_ICAdd_RshEq(U8*);
0067 import U8 * __HC_ICAdd_AndEq(U8*);
0068 import U8 * __HC_ICAdd_OrEq(U8*);
0069 import U8 * __HC_ICAdd_XorEq(U8*);
0070 import U8 * __HC_ICAdd_ModEq(U8*);
0071 import U8 * __HC_ICAdd_FReg(U8*,I64);
0072 import U8 * __HC_ICAdd_Vargs(U8 *,I64);
0073 import U8 * __HC_ICAdd_IReg(U8*,I64 r,I64 rt,I64 ptrs);
0074 import U8 * __HC_ICAdd_Frame(U8*,I64 off,I64 rt,I64 ptrs);
0075 import U8 *__HC_CodeMiscJmpTableNew(U8 *,U8 **cmts,I64 lo,I64 hi);
0076 import U8 *__HC_CodeMiscStrNew(U8*,U8*,I64 sz);
0077 import U8 *__HC_CodeMiscLabelNew(U8*,U8**patch_addr=NULL);
0078 import U8 *__HC_CmpCtrlNew();
0079 import U8 *__HC_CodeCtrlPush(U8*);
0080 import U0 __HC_CodeCtrlPop(U8*);
0081 import U8 *__HC_Compile(U8*,I64 *sz=NULL,U8 **dbg_info=NULL);
0082 import U8 *__HC_CodeMiscStrNew(U8 *,U8*,I64);
0083 import U8 *__HC_CodeMiscJmpTableNew(U8*,U8**,I64,I64);
0084 import U8 *__HC_ICAdd_Label(U8*,U8*);
0085 import U8 *__HC_ICAdd_Goto(U8*,U8*);
0086 import U8 *__HC_ICAdd_GotoIf(U8*,U8*)
0087 import U8 *__HC_ICAdd_Str(U8*,U8*); //Takes a AIWNIOS code misc
0088 import U8 *__HC_ICAdd_Neg(U8*);
0089 import U8 *__HC_ICAdd_Ret(U8*);
0090 import U8 *__HC_ICAdd_Arg(U8*,I64);
0091 import U8 *__HC_ICAdd_SetFrameSize(U8*,I64);
0092 import U8 *__HC_ICAdd_Reloc(U8 *ccmp,U8 *cc,U64*,U8 *sym,I64 rt,I64 ptrsctrl);
0093 import U8 *__HC_ICAdd_RelocUnique(U8 *ccmp,U8 *cc,U64*,U8 *sym,I64 rt,I64 ptrsctrl);
0094 import U8 *__HC_ICAdd_StaticData(U8 *ccmp,U8 *cc,I64 at,U8 *d,I64 lctrl);
0095 import U8 *__HC_ICAdd_SetStaticsSize(U8 *,I64 szctrl);
0096 import U8 *__HC_ICAdd_StaticRef(U8 *,I64 off,I64 rt,I64 ptrsctrl);
0097 import U8 *__HC_ICAdd_ShortAddr(U8 *cc,U8*cctrl,U8*,U8**);
0098 import U0 __HC_CmpCtrlSetRip(U8*,I64);
0099 import U8 * __HC_ICAdd_BT(U8*);
0100 import U8 * __HC_ICAdd_BTC(U8*);
0101 import U8 * __HC_ICAdd_BTR(U8*);
0102 import U8 * __HC_ICAdd_BTS(U8*);
0103 import U8 * __HC_ICAdd_LBTC(U8*);
0104 import U8 * __HC_ICAdd_LBTR(U8*);
0105 import U8 * __HC_ICAdd_LBTS(U8*);
0106 import U0 __HC_CodeMiscInterateThroughRefs(U8 *,U0(*fptr)(U8*addr,U8*ud),U8*user_data);
0107 import U8 * __HC_ICAdd_Fs(U8*);
0108 import U8 * __HC_ICAdd_Gs(U8*);
0109 #else
0110 extern  U8 *__HC_ICAdd_Max_I64(U8 *);
0111 extern U8 *__HC_ICAdd_Min_I64(U8 *);
0112 extern U8 *__HC_ICAdd_Max_U64(U8 *);
0113 extern U8 *__HC_ICAdd_Min_U64(U8 *);
0114 extern U8 *__HC_ICAdd_Max_F64(U8 *);
0115 extern U8 *__HC_ICAdd_Min_F64(U8 *);
0116 extern U8 *__HC_ICAdd_GetVargsPtr(U8*);
0117 extern U8 *__HC_ICAdd_RawBytes(U8*,U8*,I64);
0118 extern U0 __HC_CodeMiscInterateThroughRefs(U8 *,U0(*fptr)(U8*addr,U8*ud),U8*user_data);
0119 extern U8 * __HC_ICAdd_ToF64(U8 *);
0120 extern U8 * __HC_ICAdd_ToI64(U8 *);
0121 extern U0 __HC_ICSetLine(U8*,I64);
0122 extern U8 * __HC_ICAdd_Typecast(U8 *,I64,I64);
0123 extern U8 * __HC_ICAdd_SubCall(U8 *,U8 *);
0124 extern U8 * __HC_ICAdd_SubProlog(U8 *);
0125 extern U8 * __HC_ICAdd_SubRet(U8 *);
0126 extern U8 * __HC_ICAdd_BoundedSwitch(U8*,U8*,U8*);
0127 extern U8 * __HC_ICAdd_UnboundedSwitch(U8 *,U8 *);
0128 extern U8 * __HC_ICAdd_PreInc(U8 *,I64);
0129 extern U8 * __HC_ICAdd_Call(U8*,I64,I64 rt,I64 ptrs);
0130 extern U8 * __HC_ICAdd_F64(U8*,F64);
0131 extern U8 * __HC_ICAdd_I64(U8*,I64);
0132 extern U8 * __HC_ICAdd_PreDec(U8*,I64);
0133 extern U8 * __HC_ICAdd_PostDec(U8*,I64);
0134 extern U8 * __HC_ICAdd_PostInc(U8*,I64);
0135 extern U8 * __HC_ICAdd_Pow(U8 *);
0136 extern U8 * __HC_ICAdd_Eq(U8*);
0137 extern U8 * __HC_ICAdd_Div(U8*);
0138 extern U8 * __HC_ICAdd_Sub(U8*);
0139 extern U8 * __HC_ICAdd_Mul(U8*);
0140 extern U8 * __HC_ICAdd_Add(U8*);
0141 extern U8 * __HC_ICAdd_Deref(U8*,I64 rt,I64 ptrs);
0142 extern U8 * __HC_ICAdd_Comma(U8*);
0143 extern U8 * __HC_ICAdd_Addr(U8*);
0144 extern U8 * __HC_ICAdd_Xor(U8*);
0145 extern U8 * __HC_ICAdd_Mod(U8*);
0146 extern U8 * __HC_ICAdd_Or(U8*);
0147 extern U8 * __HC_ICAdd_Lt(U8*);
0148 extern U8 * __HC_ICAdd_Gt(U8*);
0149 extern U8 * __HC_ICAdd_Le(U8*);
0150 extern U8 * __HC_ICAdd_Ge(U8*);
0151 extern U8 * __HC_ICAdd_LNot(U8*);
0152 extern U8 * __HC_ICAdd_BNot(U8*);
0153 extern U8 * __HC_ICAdd_AndAnd(U8*);
0154 extern U8 * __HC_ICAdd_And(U8*);
0155 extern U8 * __HC_ICAdd_OrOr(U8*);
0156 extern U8 * __HC_ICAdd_XorXor(U8*);
0157 extern U8 * __HC_ICAdd_Ne(U8*);
0158 extern U8 * __HC_ICAdd_EqEq(U8*);
0159 extern U8 * __HC_ICAdd_Lsh(U8*);
0160 extern U8 * __HC_ICAdd_Rsh(U8*);
0161 extern U8 * __HC_ICAdd_AddEq(U8*);
0162 extern U8 * __HC_ICAdd_SubEq(U8*);
0163 extern U8 * __HC_ICAdd_MulEq(U8*);
0164 extern U8 * __HC_ICAdd_DivEq(U8*);
0165 extern U8 * __HC_ICAdd_LshEq(U8*);
0166 extern U8 * __HC_ICAdd_RshEq(U8*);
0167 extern U8 * __HC_ICAdd_AndEq(U8*);
0168 extern U8 * __HC_ICAdd_OrEq(U8*);
0169 extern U8 * __HC_ICAdd_XorEq(U8*);
0170 extern U8 * __HC_ICAdd_ModEq(U8*);
0171 extern U8 * __HC_ICAdd_FReg(U8*,I64);
0172 extern U8 * __HC_ICAdd_Ds(U8 *,I64);
0173 extern U8 * __HC_ICAdd_IReg(U8*,I64 r,I64 rt,I64 ptrs);
0174 extern U8 * __HC_ICAdd_Frame(U8*,I64 off,I64 rt,I64 ptrs);
0175 extern U8 *__HC_CodeMiscJmpTableNew(U8 *,U8 **cmts,I64 lo,I64 hi);
0176 extern U8 *__HC_CodeMiscStrNew(U8*,U8*,I64 sz);
0177 extern U8 *__HC_CodeMiscLabelNew(U8*,U8**);
0178 extern U8 *__HC_CmpCtrlNew();
0179 extern U8 *__HC_CodeCtrlPush(U8*);
0180 extern U0 __HC_CodeCtrlPop(U8*);
0181 extern U8 *__HC_Compile(U8*,I64 *sz=NULL,U8 **dbg_info=NULL);
0182 extern U8 *__HC_CodeMiscLabelNew(U8 *,U8 **patch_addr=NULL);
0183 extern U8 *__HC_CodeMiscStrNew(U8 *,U8*,I64);
0184 extern U8 *__HC_CodeMiscJmpTableNew(U8*,U8**,I64,I64);
0185 extern U8 *__HC_ICAdd_Label(U8*,U8*);
0186 extern U8 *__HC_ICAdd_Goto(U8*,U8*);
0187 extern U8 *__HC_ICAdd_GotoIf(U8*,U8*)
0188 extern U8 *__HC_ICAdd_Str(U8*,U8*); //Takes a AIWNIOS code misc
0189 extern U8 *__HC_ICAdd_Neg(U8*);
0190 extern U8 *__HC_ICAdd_Ret(U8*);
0191 extern U8 *__HC_ICAdd_Arg(U8*,I64);
0192 extern U8 *__HC_ICAdd_SetFrameSize(U8*,I64);
0193 extern U8 *__HC_ICAdd_Reloc(U8 *ccmp,U8 *cc,U64*,U8 *sym,I64 rt,I64 ptrsctrl);
0194 extern U8 *__HC_ICAdd_StaticData(U8 *ccmp,U8 *cc,I64 at,U8 *d,I64 lctrl);
0195 extern U8 *__HC_ICAdd_SetStaticsSize(U8 *,I64 szctrl);
0196 extern U8 *__HC_ICAdd_StaticRef(U8 *,I64 off,I64 rt,I64 ptrsctrl);
0197 extern U8 *__HC_ICAdd_ShortAddr(U8 *cc,U8*cctrl,U8*,U8**);
0198 extern U0 __HC_CmpCtrlSetRip(U8*,I64);
0199 extern U8 * __HC_ICAdd_BT(U8*);
0200 extern U8 * __HC_ICAdd_BTC(U8*);
0201 extern U8 * __HC_ICAdd_BTR(U8*);
0202 extern U8 * __HC_ICAdd_BTS(U8*);
0203 extern U8 * __HC_ICAdd_LBTC(U8*);
0204 extern U8 * __HC_ICAdd_LBTR(U8*);
0205 extern U8 * __HC_ICAdd_LBTS(U8*);
0206 extern U8 * __HC_ICAdd_Fs(U8*);
0207 extern U8 * __HC_ICAdd_Gs(U8*)
0208 #endif
0209 //
0210 // See arm_backend.c
0211 //
0212 #ifdef TARGET_AARCH64
0213 #define AIWNIOS_IREG_START 19
0214 #define AIWNIOS_IREG_CNT (28 - 19 + 1)
0215 #define AIWNIOS_FREG_START 8
0216 #define AIWNIOS_FREG_CNT (15 - 8 + 1)
0217 #endif
0218 
0219 #ifdef TARGET_X86
0220 #define REG_RAX 0
0221 #define REG_RCX 1
0222 #define REG_RDX 2
0223 #define REG_RBX 3
0224 #define REG_RSP 4
0225 #define REG_RBP 5
0226 #define REG_RSI 6
0227 #define REG_RDI 7
0228 #define REG_R8 8
0229 #define REG_R9 9
0230 #define REG_R10 10
0231 #define REG_R11 11
0232 #define REG_R12 12
0233 #define REG_R13 13
0234 #define REG_R14 14
0235 #define REG_R15 15
0236 #define REG_RIP 16
0237 #define AIWNIOS_IREG_START 9
0238 #define AIWNIOS_IREG_CNT 7
0239 #define AIWNIOS_TMP_IREG_CNT 3
0240 #define AIWNIOS_REG_FP REG_RBP
0241 #define AIWNIOS_REG_SP REG_RSP
0242 #define AIWNIOS_TMP_IREG_START 0
0243 #define AIWNIOS_FREG_START 6
0244 #define AIWNIOS_FREG_CNT (15-6+1)
0245 #define AIWNIOS_TMP_FREG_START 2
0246 #define AIWNIOS_TMP_FREG_CNT 14
0247 #endif
0248 //
0249 // Replaces IC_CALL_INDIRECT(IC_ADDR_IMPORT) with Short jumps if not import
0250 //
0251 U0 AiwniosMakeShortJmps(CCmpCtrl *cc,U8 *cc2) {
0252   CRPN *head=&cc->coc.coc_head,*cur,*new;
0253   CCodeMisc *misc;
0254   for(cur=head->next;cur!=head;cur=cur->next) {
0255     if(cur->type==IC_ADDR_IMPORT) {
0256       misc=cur->ic_data;
0257       if(!(misc->h->type&HTF_IMPORT)) {
0258 force:
0259         cur->misc=misc;
0260         cur->misc->flags|=CMF_SHORT_ADDR;
0261         cur->misc->addr=__HC_CodeMiscLabelNew(cc2);
0262         cur->ic_flags|=ICF_SHORT_JMP;
0263       } else {
0264 /* Nroot removed this as not all platforms have easy access to lower 32bits
0265 #ifdef TARGET_X86
0266 //In X86_64,i will put all functions in low 32bits to avoid viener functions.
0267 goto force;
0268 #endif
0269 */
0270       }
0271     }
0272   }
0273 }
0274 #ifdef TARGET_X86
0275 I64 VarIRegToReg(I64 r)  {
0276         switch(r) {
0277                 break;case 0: return REG_R10;
0278                 break;case 1: return REG_R11;
0279                 break;case 2: return REG_R12;
0280                 break;case 3: return REG_R14;
0281                 break;case 4: return REG_R15;
0282                 break;case 5: return REG_RDI;
0283                 break;case 6: return REG_RSI;
0284         }
0285         throw('Compile');
0286 }
0287 #endif
0288 class CAddShortRelocData {
0289         CCmpCtrl *cc;
0290         CCodeMisc *cm;
0291         U8 *machine_code;
0292 };
0293 U0 AddShortReloc(U8 *addr,CAddShortRelocData *data) {
0294   CAOTImportExport *tmpaie=CAlloc(sizeof(CAOTImportExport));
0295   tmpaie->type=IET_REL_I32;
0296   tmpaie->str=StrNew(data->cm->h->str);
0297   tmpaie->rip=data->cc->aotc->rip+(addr-data->machine_code);
0298   tmpaie->offset=data->cm->offset;
0299   tmpaie->short_jmp=TRUE;
0300   QueIns(tmpaie,data->cc->aot->last_ie);
0301 }
0302 static Bool IsTLSReloc(CCodeMisc *misc) {
0303   if(misc->h&&(!StrCmp(misc->h->str,"__Fs")||!StrCmp(misc->h->str,"__Gs")))
0304         return TRUE;
0305   return FALSE;
0306 }
0307 static Bool IsFunArg(CHashFun *fun,CMemberLst *lst) {
0308   if(!fun) return FALSE;
0309   CMemberLst *mlst=fun->member_lst_and_root;
0310   I64 idx;
0311   for(idx=0;idx!=fun->arg_cnt;idx++) {
0312     if(lst==mlst) return TRUE;
0313     mlst=mlst->next;
0314   }
0315   return FALSE;
0316 }
0317 static I64 FunArgIdx(CHashFun *fun,CMemberLst *lst) {
0318   if(!fun) return FALSE;
0319   CMemberLst *mlst=fun->member_lst_and_root;
0320   I64 idx;
0321   for(idx=0;idx!=fun->arg_cnt;idx++) {
0322     if(lst==mlst) return idx;
0323     mlst=mlst->next;
0324   }
0325   return -1;
0326 }
0327 
0328 //
0329 // Turns my CRPN from the parser into the IC for the C side
0330 //
0331 U8 *AiwniosCompile(CCmpCtrl *cc,I64 *res_sz=NULL,CDbgInfo **info) {
0332   CRPN *head=&cc->coc.coc_head,*cur,*new;
0333   CCodeMisc *misc,**table;
0334   CMemberLst *mlst;
0335   COptMemberVar *mv=NULL;
0336   CHashImport *h;
0337   CAOTImportExport *tmpaie;
0338   CAOTAbsAddr *tmpabs;
0339   CAddShortRelocData fill_user_data;
0340   I64 idx,argc,member_cnt=0,ir=AIWNIOS_IREG_START,fr=AIWNIOS_FREG_START,foff,*foff_lookup=NULL,align;
0341   U8 **aiwnios_dbg_info=NULL;
0342   U8 *acc=__HC_CmpCtrlNew(),*machine_code;
0343   I64 *table_ptr;
0344   U8 *cc2=__HC_CodeCtrlPush(acc);
0345   if(GetOption(OPTf_BOUNDS_CHECK)&&HashFind("WhineOOB",cc->htc.glbl_hash_table,HTT_FUN)) {
0346     for(cur=head->next;cur!=head;cur=cur->next) {
0347       if(cur->type==IC_DEREF) {
0348         new=CAlloc(sizeof CRPN);
0349         new->type=IC_ADDR_IMPORT;
0350         new->ic_class=cmp.internal_types[RT_I64];
0351         new->ic_data=CodeMiscHashNew(cc,HashFind("WhineOOB",cc->htc.glbl_hash_table,HTT_FUN));
0352         QueInsRev(new,RPNNext(cur)); 
0353         new=CAlloc(sizeof CRPN);
0354         new->type=IC_CALL_INDIRECT;
0355         new->length=2;
0356         new->ic_class=cmp.internal_types[RT_I64];
0357         QueIns(new,cur);
0358       }
0359     }    
0360   }
0361   #ifdef TARGET_X86
0362   if(cc->flags&CCF_AOT_COMPILE)
0363     AiwniosMakeShortJmps(cc,acc);
0364   #endif
0365   if(cc->flags&CCF_AOT_COMPILE)
0366     __HC_CmpCtrl_SetAOT(acc);
0367   if(info) {
0368     idx=cc->max_line-cc->min_line;
0369     *info=MAlloc((idx+2)*8+sizeof(CDbgInfo));
0370     info[0]->min_line=cc->min_line;
0371     info[0]->max_line=cc->max_line;
0372   }
0373   //
0374   // Step 1,do register allocation stuff by counting the occuraces of IC_FRAME,and making
0375   //  sure arent getting the address of said location
0376   //
0377   if(cc->htc.fun) {
0378     member_cnt=cc->htc.fun->member_cnt;
0379     mlst=cc->htc.fun->member_lst_and_root;
0380     if(cc->htc.fun->flags&(1<<Ff_DOT_DOT_DOT)) {
0381       member_cnt+=2;
0382     }
0383     mv=CAlloc(member_cnt*sizeof COptMemberVar);
0384     foff_lookup=CAlloc(member_cnt*sizeof I64);
0385     for(idx=0;idx!=member_cnt;idx++) {
0386       mv[idx].m=mlst;
0387       mlst=mlst->next;
0388     }
0389     for(cur=head->last;cur!=head;cur=cur->last) {
0390       if(cur->type==IC_FRAME) {
0391         mlst=cc->htc.fun->member_lst_and_root;
0392         for(idx=0;idx!=member_cnt;idx++) {
0393           if(cur->ic_data==mv[idx].m->offset) {
0394             if(cur->last(CRPN*)->type==IC_ADDR) {
0395               mv[idx].addrof_cnt++;
0396               mv[idx].score=0;
0397             }
0398             if(!mv[idx].addrof_cnt)
0399               mv[idx].score++;
0400             break;
0401           }
0402           mlst=mlst->next;
0403         }
0404       }
0405     }
0406     //Sort by score
0407     QSort(mv,member_cnt,sizeof(COptMemberVar),&OptMVCompare);
0408     for(idx=0;idx!=member_cnt;idx++) {
0409       if(mv[idx].m->reg!=REG_NONE&&mv[idx].score&&!mv[idx].m->dim.next) {
0410         if(mv[idx].m->member_class->raw_type==RT_F64) {
0411           if(AIWNIOS_FREG_START<=fr<AIWNIOS_FREG_START+AIWNIOS_FREG_CNT) {
0412             mv[idx].m->reg=fr++;
0413           } else
0414             mv[idx].m->reg=REG_NONE;
0415         } else {
0416           if(AIWNIOS_IREG_START<=ir<AIWNIOS_IREG_START+AIWNIOS_IREG_CNT) {
0417             #ifdef TARGET_X86
0418             mv[idx].m->reg=VarIRegToReg(ir++ -AIWNIOS_IREG_START);
0419             #else
0420             mv[idx].m->reg=ir++;
0421             #endif
0422           } else {
0423             mv[idx].m->reg=REG_NONE;
0424           }
0425         }
0426       } else
0427         mv[idx].m->reg=REG_NONE;
0428     }
0429     
0430     //Assign registers
0431     for(cur=head->last;cur!=head;cur=cur->last) {
0432       if(cur->type==IC_FRAME) {
0433         for(idx=0;idx!=member_cnt;idx++) {
0434           if(cur->ic_data==mv[idx].m->offset) {          
0435             if(mv[idx].m->reg!=REG_NONE) {
0436               cur->type=IC_REG;
0437               cur->ic_data=mv[idx].m->reg;
0438             }
0439             break;
0440           }
0441         }
0442       }
0443     }
0444     //In FunRep,the function is assumes to store registers somewhere
0445     //So i "store" them at the start of the function
0446     foff=0;
0447     for(idx=0;idx!=member_cnt;idx++) {
0448       if(mv[idx].m->reg!=REG_NONE) {
0449         mv[idx].m->offset=foff;
0450         foff+=8;
0451       }
0452     }
0453     //Assign offsets
0454     for(idx=0;idx!=member_cnt;idx++) {
0455       mlst=mv[idx].m;
0456 //idx here is the alignment
0457       align=8;
0458       if(mlst->reg==REG_NONE) {
0459         #ifdef TARGET_AARCH64
0460         foff_lookup[idx].i32[1]=foff;
0461         foff_lookup[idx].i32[0]=mlst->offset;
0462         mlst->offset=foff;
0463         foff+=mlst->member_class->size*mlst->dim.total_cnt;  
0464         if(foff&(align-1))
0465           foff+=align-(foff&(align-1)); //Align to 8
0466         #endif
0467         #ifdef TARGET_X86
0468         if(IsFunArg(cc->htc.fun,mlst)&&!(mlst->flags&MLF_DOT_DOT_DOT&&!StrCmp(mlst->str,"argv"))) {
0469           //Arguments are passed on stack so no need to mode
0470           foff_lookup[idx].i32[0]=mlst->offset;
0471           //16 to offset [PC,RBP] pair at base 
0472           mlst->offset=-16-8*FunArgIdx(cc->htc.fun,mlst);
0473       foff_lookup[idx].i32[1]=mlst->offset;
0474         } else {
0475           foff_lookup[idx].i32[0]=mlst->offset;
0476           //In X86_64 the stack grows down and the RBP is above the stack pointer,
0477           //SO MOVE THE OFFSETS DOWN TO THE BOTTOM
0478           //RBP
0479           //x0
0480           //x1
0481           //....
0482           //x8 <<=offset
0483           foff+=mlst->member_class->size*mlst->dim.total_cnt;  
0484           if(foff&(align-1))
0485             foff+=align-(foff&(align-1)); //Align to 8
0486           mlst->offset=foff;
0487           foff_lookup[idx].i32[1]=foff;
0488         }
0489         #endif
0490       } else {
0491 //Assign  them a spot on the stack for debugging purposes
0492         foff+=8;
0493         if(foff&7)
0494           foff+=8-(foff&7); //Align to 8
0495         mlst->offset=foff;
0496       }
0497     }
0498     if(foff&7)
0499       foff+=8-(foff&7); //Align to 8    
0500     cc->htc.fun->size=foff;
0501   }
0502   
0503   //Replace the old frame address with the new one 
0504   for(cur=head->last;cur!=head;cur=cur->last)
0505     if(cur->type==IC_FRAME)
0506       for(idx=0;idx!=member_cnt;idx++) {
0507         foff=foff_lookup[idx].i32[0];
0508         if(foff==cur->ic_data) {
0509           cur->ic_data=foff_lookup[idx].u32[1];
0510           break;
0511         }
0512       }
0513   Free(foff_lookup);
0514   
0515   //
0516   // Step 1.5,Assign the variables from the arguments
0517   //
0518   if(cc->htc.fun) {
0519     __HC_ICAdd_SetFrameSize(cc2,cc->htc.fun->size+16);
0520     mlst=cc->htc.fun->member_lst_and_root;
0521     argc=cc->htc.fun->arg_cnt;
0522    if(cc->htc.fun->flags&(1<<Ff_DOT_DOT_DOT))
0523       argc+=2;
0524     for(idx=0;idx!=argc;idx++) {
0525       if(mlst->reg==REG_NONE)
0526         __HC_ICAdd_Frame(cc2,mlst->offset,mlst->member_class->raw_type,0);
0527       else if(mlst->member_class->raw_type!=RT_F64) {
0528         __HC_ICAdd_IReg(cc2,mlst->reg,mlst->member_class->raw_type,0);
0529       } else {
0530         __HC_ICAdd_FReg(cc2,mlst->reg);      
0531       }
0532 
0533 #ifdef TARGET_X86
0534 //Not yet implemented for AARCH64
0535       if(mlst->flags&MLF_DOT_DOT_DOT&&!StrCmp(mlst->str,"argv")) {
0536         __HC_ICAdd_GetVargsPtr(cc2);
0537       } else
0538         __HC_ICAdd_Arg(cc2,idx);
0539 #endif
0540 #ifdef TARGET_AARCH64
0541         __HC_ICAdd_Arg(cc2,idx);
0542 #endif
0543       mlst=mlst->next;
0544     }
0545     Free(mv);
0546   } else {
0547     //
0548     // Add MANDITORY room for FP/LR pair
0549     //
0550     __HC_ICAdd_SetFrameSize(cc2,16);
0551   }
0552   //
0553   //
0554   // Step 2,convert CCodeMisc's to AIWNIOS codegen CCodeMiscs
0555   //
0556   for(misc=cc->coc.coc_next_misc;misc!=&cc->coc.coc_next_misc;misc=misc->next) {
0557     switch(misc->type) {
0558     break;case CMT_HASH_ENTRY:
0559       //See spider thing for more notes 
0560     break;case CMT_LABEL:
0561       misc->addr=__HC_CodeMiscLabelNew(acc,&misc->addr2);
0562     break;case CMT_GOTO_LABEL:
0563       if(!(misc->flags&CMF_DEFINED)&&misc->str) {
0564         PrintErr("Undefined reference to label \"%s\".\n",misc->str);
0565         LexExcept(cc,"Undefined label reference");
0566       }
0567       misc->addr=__HC_CodeMiscLabelNew(acc,&misc->addr2);
0568     break;case CMT_STR_CONST:
0569       misc->addr=__HC_CodeMiscStrNew(acc,misc->str,misc->st_len);
0570     //
0571     // Skip this for now,we want to assign the labels AIWNIOS codegen CCodeMiscs to
0572     //  the labels and we will pass the labels'->addr to __HC_CodeMiscJmpTableNew
0573     //break;case CMT_JMP_TABLE:
0574     //  misc->addr=__HC_CodeMiscJmpTableNew(cc2);
0575     //
0576     }
0577   }
0578   //See above note
0579   for(misc=cc->coc.coc_next_misc;misc!=&cc->coc.coc_next_misc;misc=misc->next) {
0580     if(misc->type==CMT_JMP_TABLE) {
0581       table=CAlloc(misc->range*8);
0582       for(idx=0;idx!=misc->range;idx++)
0583         table[idx]=misc->jmp_table[idx]->addr;
0584       misc->addr=__HC_CodeMiscJmpTableNew(acc,table,&misc->addr2,misc->range);
0585       Free(table);
0586     }
0587   }
0588   //
0589   // Step 3,Convert static addresses to static offsets and compute statics size
0590   //
0591   if(cc->htc.fun) {
0592     //
0593     // foff_lookup will have form [orig_static_data1,offset1,...,orig_static_dataN,offsetN]
0594     //
0595     foff=0;
0596     foff_lookup=CAlloc(2*member_cnt*8);
0597     mlst=cc->htc.fun->member_lst_and_root;
0598     for(idx=0;idx!=member_cnt;idx++) {
0599       if(mlst->flags&MLF_STATIC) {
0600         __HC_ICAdd_StaticData(acc,cc2,foff,mlst->static_data,mlst->member_class->size*mlst->dim.total_cnt);
0601         foff_lookup[idx*2]=mlst->static_data;
0602         foff_lookup[idx*2+1]=foff;
0603         foff+=mlst->member_class->size*mlst->dim.total_cnt;
0604         if(foff%8)
0605           foff+=8-foff%8;
0606       }
0607       mlst=mlst->next;
0608     }
0609     if(foff) {
0610       for(cur=head->last;cur!=head;cur=cur->last) {
0611         if(cur->type==IC_STATIC) {
0612           mlst=cc->htc.fun->member_lst_and_root;
0613           for(idx=0;idx!=member_cnt;idx++) {
0614             if(foff_lookup[idx*2]==cur->ic_data) {
0615               cur->ic_data=foff_lookup[idx*2+1];
0616               break;
0617             }
0618             mlst=mlst->next;
0619           }
0620         }
0621       }
0622       __HC_ICAdd_SetStaticsSize(cc2,foff);
0623     }
0624     Free(foff_lookup);
0625   }
0626   //
0627   // Step 4,OptClassFwd the ic_class'es to reduce to I64 to I64i's etc
0628   //
0629   // Classes with base type's need to be OptClassFwd'ed to reduce down to thier base type,otherwise
0630   //   it is probably an RT_I64
0631   for(cur=head->last;cur!=head;cur=cur->last) {
0632     if(cur->ic_class)
0633       cur->ic_class=OptClassFwd(cur->ic_class);
0634   }
0635   //
0636   // Step 6,convert the CRPN's into AIWNIOS rpns
0637   //
0638   for(cur=head->last;cur!=head;cur=cur->last) {
0639     switch(cur->type) {
0640     break;case IC_MAX_I64:
0641       new=__HC_ICAdd_Max_I64(cc2);
0642     break;case IC_MAX_U64:
0643       new=__HC_ICAdd_Max_U64(cc2);
0644     break;case IC_MIN_I64:
0645       new=__HC_ICAdd_Min_I64(cc2);
0646     break;case IC_MIN_U64:
0647       new=__HC_ICAdd_Min_U64(cc2);
0648     break;case IC_FS:
0649     if(!cur->ic_data) {
0650     //Unique references to the TLS offset(unlike normal functions whose pointer is stored at the end of the function and loaded from there)
0651       misc=cur->ic_data=COCMiscNew(cc,CMT_HASH_ENTRY);
0652       misc->h=HashFind("__Fs",cc->htc.glbl_hash_table,HTT_FUN);
0653       if(!misc->h)
0654         misc->h=HashFind("__Fs",Fs->hash_table,HTT_FUN); //Maybe we arent AOT Compiling
0655     }
0656     misc=cur->ic_data;
0657     misc->addr=INVALID_PTR;
0658     if(!(misc->h->type&HTF_IMPORT)) {
0659       new=__HC_ICAdd_I64(cc2,misc->h(CHashFun*)->exe_addr);
0660     } else
0661       new=__HC_ICAdd_RelocUnique(
0662           acc,
0663           cc2,
0664           &misc->addr,
0665           "__Fs",
0666           RT_U8,
0667           1
0668         );
0669     new=__HC_ICAdd_Fs(cc2);
0670         break;case IC_GS:
0671         if(!cur->ic_data) {
0672     //Unique references to the TLS offset(unlike normal functions whose pointer is stored at the end of the function and loaded from there)
0673       misc=cur->ic_data=COCMiscNew(cc,CMT_HASH_ENTRY);
0674       misc->h=HashFind("__Gs",cc->htc.glbl_hash_table,HTT_FUN);
0675       if(!misc->h)
0676         misc->h=HashFind("__Gs",Fs->hash_table,HTT_FUN); //Maybe we arent AOT Compiling
0677     }
0678     misc=cur->ic_data;
0679     misc->addr=INVALID_PTR;
0680     if(!(misc->h->type&HTF_IMPORT)) {
0681       new=__HC_ICAdd_I64(cc2,misc->h(CHashFun*)->exe_addr);
0682     } else
0683       new=__HC_ICAdd_RelocUnique(
0684           acc,
0685           cc2,
0686           &misc->addr,
0687           "__Gs",
0688           RT_U8,
0689           1
0690         );
0691     new=__HC_ICAdd_Gs(cc2);
0692             break;case IC_LOCK:
0693     new=__HC_ICAdd_Lock(cc2);    
0694     break;case IC_FRAME:
0695     if(cur->last(CRPN*)->type==IC_ADDR) {
0696       //Our HolyC part accounts for the pointers for us
0697       new=__HC_ICAdd_Frame(cc2,cur->ic_data,RT_U8,0);
0698     } else if(cur->ic_class->ptr_stars_cnt)
0699       //All pointer arithmetic is pre-computed
0700       new=__HC_ICAdd_Frame(cc2,cur->ic_data,RT_PTR,0);
0701     else if(!cur->ic_dim)
0702       new=__HC_ICAdd_Frame(cc2,cur->ic_data,cur->ic_class->raw_type,0);
0703     else
0704       new=__HC_ICAdd_Frame(cc2,cur->ic_data,RT_I64,0);
0705     break;case IC_BR_ZERO:
0706     new=__HC_ICAdd_LNot(cc2);
0707     __HC_ICSetLine(new,cur->ic_line);
0708     new=__HC_ICAdd_GotoIf(cc2,cur->ic_data(CCodeMisc*)->addr);
0709     break;case IC_BR_NOT_ZERO:
0710     new=__HC_ICAdd_GotoIf(cc2,cur->ic_data(CCodeMisc*)->addr);
0711     //break;case IC_BR_CARRY: ???
0712     //break;case IC_BR_NOT_CARRY: ???
0713     break;case IC_BR_EQU_EQU:
0714     new=__HC_ICAdd_EqEq(cc2);
0715     __HC_ICSetLine(new,cur->ic_line);
0716     new=__HC_ICAdd_GotoIf(cc2,cur->ic_data(CCodeMisc*)->addr);
0717     break;case IC_BR_NOT_EQU:
0718     new=__HC_ICAdd_Ne(cc2);
0719     __HC_ICSetLine(new,cur->ic_line);
0720     new=__HC_ICAdd_GotoIf(cc2,cur->ic_data(CCodeMisc*)->addr);
0721     break;case IC_BR_LESS:
0722     new=__HC_ICAdd_Lt(cc2);
0723     __HC_ICSetLine(new,cur->ic_line);
0724     new=__HC_ICAdd_GotoIf(cc2,cur->ic_data(CCodeMisc*)->addr);
0725     break;case IC_BR_GREATER_EQU:
0726     new=__HC_ICAdd_Ge(cc2);
0727     __HC_ICSetLine(new,cur->ic_line);
0728     new=__HC_ICAdd_GotoIf(cc2,cur->ic_data(CCodeMisc*)->addr);
0729     break;case IC_BR_GREATER:
0730     new=__HC_ICAdd_Gt(cc2);
0731     __HC_ICSetLine(new,cur->ic_line);
0732     new=__HC_ICAdd_GotoIf(cc2,cur->ic_data(CCodeMisc*)->addr);
0733     break;case IC_BR_LESS_EQU:
0734     new=__HC_ICAdd_Le(cc2);
0735     __HC_ICSetLine(new,cur->ic_line);
0736     new=__HC_ICAdd_GotoIf(cc2,cur->ic_data(CCodeMisc*)->addr);
0737     //break;case IC_BR_EQU_EQU2: ???
0738     //break;case IC_BR_NOT_EQU2:  ???
0739     //break;case IC_BR_LESS2 ???
0740     //break;case IC_BR_GREATER_EQU2 ???
0741     //break;case IC_BR_GREATER2 ???
0742     //break;case IC_BR_LESS_EQU2 ???
0743     //break;case IC_BR_AND_ZERO ???
0744     //break;case IC_BR_AND_NOT_ZERO ???
0745     //break;case IC_BR_MM_ZERO ???
0746     //break;case IC_BR_MM_NOT_ZERO ???
0747     //break;case IC_BR_AND_AND_ZERO ???
0748     //break;case IC_BR_AND_AND_NOT_ZERO ???
0749     //break;case IC_BR_OR_OR_ZERO ???
0750     //break;case IC_BR_OR_OR_NOT_ZERO ???
0751     break;case IC_END: //This is symbolic 
0752     break;case IC_NOP1:
0753     break;case IC_END_EXP:
0754     break;case IC_NOP2:
0755     break;case IC_LABEL:
0756       new=__HC_ICAdd_Label(cc2,cur->ic_data(CCodeMisc*)->addr);
0757 break;case IC_ASM:
0758   __HC_ICAdd_Label(cc2,__HC_CodeMiscLabelNew(acc,&cur->ic_data(CAiwniosAOTBlob*)->final_start_addr));
0759    new=__HC_ICAdd_RawBytes(cc2,cur->ic_data(CAiwniosAOTBlob*)->data,cur->ic_data(CAiwniosAOTBlob*)->len);
0760             
0761 //break;case IC_CALL_START: AIWNIOS DOESNT USE THESE
0762     //break;case IC_CALL_END:
0763     //break;case IC_CALL_END2:
0764     //break;case IC_RETURN_VAL:
0765     //break;case IC_RETURN_VAL2:
0766     break;case IC_IMM_I64:
0767     new=__HC_ICAdd_I64(cc2,cur->imm_i64);
0768     break;case IC_IMM_F64:
0769     new=__HC_ICAdd_F64(cc2,cur->imm_f64);
0770     break;case IC_STR_CONST:
0771     new=__HC_ICAdd_Str(cc2,cur->ic_data(CCodeMisc*)->addr);
0772     break;case IC_ABS_ADDR:
0773     misc=COCMiscNew(cc,CMT_LABEL);
0774     misc->str=MStrPrint("0x%x",cur->imm_i64);
0775     misc->addr=INVALID_PTR;
0776     new=__HC_ICAdd_Reloc(
0777           acc,
0778           cc2,
0779           &misc->addr,
0780           misc->str,
0781           RT_U8,
0782           1
0783         );
0784     break;case IC_ADDR_IMPORT:
0785     //
0786     //Aiwnios ALWAYS takes 1 import misc for each IMPORTED symbol(which can
0787     //  be looked up multiple times by the function)
0788     //          _____
0789     // ________/     \________
0790     // | |   /( ^___^ )\   | |
0791     // | |  | /( \_/ )\ |  | |
0792     // | |  | | \___/ | |  | |
0793     //_/_| _|_|       |_|_ |_ \_
0794     //
0795     h=cur->ic_data(CCodeMisc*)->h;
0796     if(cur->ic_flags&ICF_SHORT_JMP) {
0797       new=__HC_ICAdd_ShortAddr(acc,cc2,h->str,cur->ic_data(CCodeMisc*)->addr);
0798       break;
0799     }
0800     if(h->type&HTT_GLBL_VAR) {
0801       if((h(CHashGlblVar*)->flags&GVF_EXTERN)||cc->flags&CCF_AOT_COMPILE) {
0802         new=__HC_ICAdd_Reloc(
0803           acc,
0804           cc2,
0805           &cur->ic_data(CCodeMisc*)->addr,
0806           h->str,
0807           RT_U8,
0808           1
0809         );
0810       } else {
0811         new=__HC_ICAdd_I64(
0812           cc2,
0813           h(CHashGlblVar*)->data_addr
0814         );
0815       }
0816     } else if(h->type&HTT_FUN) {
0817       if((h(CHashFun*)->flags&(1<<Cf_EXTERN))||cc->flags&CCF_AOT_COMPILE) {
0818         new=__HC_ICAdd_Reloc(
0819             acc,
0820             cc2,
0821             &cur ->ic_data(CCodeMisc*)->addr,
0822             h->str,
0823             RT_U8,
0824             1
0825           );
0826       } else {
0827         new=__HC_ICAdd_I64(
0828           cc2,
0829           h(CHashFun*)->exe_addr
0830         );
0831       }
0832     } else if(!(h->type&HTF_RESOLVE)) {
0833         new=__HC_ICAdd_Reloc(
0834             acc,
0835             cc2,
0836             &cur ->ic_data(CCodeMisc*)->addr,
0837             h->str,
0838             RT_U8,
0839             1
0840           );
0841     } else {
0842         new=__HC_ICAdd_I64(
0843           cc2,
0844           h(CHashExport*)->val
0845         );
0846     }
0847     if(cc->flags&CCF_AOT_COMPILE) {
0848       if(h->type&HTT_GLBL_VAR&&h->type&HTF_EXPORT) {
0849         __HC_SetAOTRelocBeforeRIP(new,h(CHashGlblVar*)->data_addr_rip-cc->aotc->rip);
0850       } else if(h->type&HTT_FUN&&!Bt(&(h(CHashFun*)->flags),Cf_EXTERN)) {
0851         __HC_SetAOTRelocBeforeRIP(new,h(CHashFun*)->exe_addr-cc->aotc->rip);
0852       }
0853     }
0854     break;case IC_REG:
0855     if(cur->ic_dim) {
0856         new=__HC_ICAdd_IReg(cc2,cur->imm_i64,cmp.internal_types[RT_I64],0);
0857     } else {
0858       if(cur->ic_class->raw_type==RT_F64) {
0859         new=__HC_ICAdd_FReg(cc2,cur->imm_i64);
0860       } else {
0861         new=__HC_ICAdd_IReg(cc2,cur->imm_i64,cur->ic_class->raw_type,0);
0862       }
0863     }
0864     break;case IC_TO_I64:
0865     new=__HC_ICAdd_ToI64(cc2);
0866     break;case IC_TO_F64:
0867     new=__HC_ICAdd_ToF64(cc2);
0868     break;case IC_TO_BOOL: //TODO
0869     break;case IC_TOUPPER:  //TODO
0870     break;case IC_HOLYC_TYPECAST:
0871     new=__HC_ICAdd_Typecast(cc2,cur->ic_class->raw_type,0);
0872     break;case IC_ADDR:
0873     new=__HC_ICAdd_Addr(cc2);
0874     break;case IC_COMMA:
0875     new=__HC_ICAdd_Comma(cc2);
0876     break;case IC_COM:
0877     new=__HC_ICAdd_BNot(cc2);
0878     break;case IC_NOT:
0879     new=__HC_ICAdd_LNot(cc2);
0880     break;case IC_UNARY_MINUS:
0881     new=__HC_ICAdd_Neg(cc2);
0882     break;case IC_DEREF:
0883     new=__HC_ICAdd_Deref(cc2,cur->ic_class->raw_type,0);
0884     //break;case IC_DEREF_PP //NOT USED BY AIWINIOS
0885     //break;case IC_DEREF_MM //DITTO
0886     break;case IC__PP:
0887     new=__HC_ICAdd_PostInc(cc2,cur->ic_data);
0888     break;case IC__MM:
0889     new=__HC_ICAdd_PostDec(cc2,cur->ic_data);
0890     break;case IC_PP_:
0891     new=__HC_ICAdd_PreInc(cc2,cur->ic_data);
0892     break;case IC_MM_:
0893     new=__HC_ICAdd_PreDec(cc2,cur->ic_data);
0894     break;case IC_SHL:
0895     new=__HC_ICAdd_Lsh(cc2);
0896     break;case IC_SHR:
0897     new=__HC_ICAdd_Rsh(cc2);
0898     //break;case IC_SHL_CONST: NOT USED BY AIWNIOS
0899     //break;case IC_SHR_CONST: NOT USED BY AIWNIOS
0900     break;case IC_POWER:
0901     throw("Compiler");
0902     break;case IC_MUL:
0903     new=__HC_ICAdd_Mul(cc2);
0904     break;case IC_DIV:
0905     new=__HC_ICAdd_Div(cc2);
0906     break;case IC_MOD:
0907     new=__HC_ICAdd_Mod(cc2);
0908     break;case IC_AND:
0909     new=__HC_ICAdd_And(cc2);
0910     break;case IC_OR:
0911     new=__HC_ICAdd_Or(cc2);
0912     break;case IC_XOR:
0913     new=__HC_ICAdd_Xor(cc2);
0914     break;case IC_BT:
0915     new=__HC_ICAdd_BT(cc2);
0916     break;case IC_BTS:
0917     new=__HC_ICAdd_BTS(cc2);
0918     break;case IC_BTC:
0919     new=__HC_ICAdd_BTC(cc2);
0920     break;case IC_BTR:
0921     new=__HC_ICAdd_BTR(cc2);
0922     break;case IC_LBTS:
0923     new=__HC_ICAdd_LBTS(cc2);
0924     break;case IC_LBTC:
0925     new=__HC_ICAdd_LBTC(cc2);
0926     break;case IC_LBTR:
0927     new=__HC_ICAdd_LBTR(cc2);
0928     break;case IC_ADD:
0929     new=__HC_ICAdd_Add(cc2);
0930     break;case IC_SUB:
0931     new=__HC_ICAdd_Sub(cc2);
0932     //break;case IC_ADD_CONST NOT USED BY AIWNIOS
0933     //break;case IC_SUB_CONST NOT USED BY AIWNIOS
0934     break;case IC_EQU_EQU:
0935     new=__HC_ICAdd_EqEq(cc2);
0936     break;case IC_NOT_EQU:
0937     new=__HC_ICAdd_Ne(cc2);
0938     break;case IC_LESS:
0939     new=__HC_ICAdd_Lt(cc2);
0940     break;case IC_GREATER_EQU:
0941     new=__HC_ICAdd_Ge(cc2);
0942     break;case IC_GREATER:
0943     new=__HC_ICAdd_Gt(cc2);
0944     break;case IC_LESS_EQU:
0945     new=__HC_ICAdd_Le(cc2);
0946     //break;case IC_PUSH_CMP NOT USED BY AIWNIOS
0947     break;case IC_AND_AND:
0948     new=__HC_ICAdd_AndAnd(cc2);
0949     break;case IC_OR_OR:
0950     new=__HC_ICAdd_OrOr(cc2);
0951     break;case IC_XOR_XOR:
0952     new=__HC_ICAdd_XorXor(cc2);
0953     break;case IC_ASSIGN:
0954     new=__HC_ICAdd_Eq(cc2);
0955     //break;case IC_ASSIGN_PP //NOT USED BY AIWNIOS
0956     //break;case IC_ASSIGN_MM //DITTO
0957     break;case IC_SHL_EQU:
0958     new=__HC_ICAdd_LshEq(cc2);
0959     break;case IC_SHR_EQU:
0960     new=__HC_ICAdd_RshEq(cc2);
0961     break;case IC_MUL_EQU:
0962     new=__HC_ICAdd_MulEq(cc2);
0963     break;case IC_DIV_EQU:
0964     new=__HC_ICAdd_DivEq(cc2);
0965     break;case IC_MOD_EQU:
0966     new=__HC_ICAdd_ModEq(cc2);
0967     break;case IC_AND_EQU:
0968     new=__HC_ICAdd_AndEq(cc2);
0969     break;case IC_OR_EQU:
0970     new=__HC_ICAdd_OrEq(cc2);
0971     break;case IC_XOR_EQU:
0972     new=__HC_ICAdd_XorEq(cc2);
0973     break;case IC_ADD_EQU:
0974     new=__HC_ICAdd_AddEq(cc2);
0975     break;case IC_SUB_EQU:
0976     new=__HC_ICAdd_SubEq(cc2);
0977     break;case IC_JMP:
0978     new=__HC_ICAdd_Goto(cc2,cur->ic_data(CCodeMisc*)->addr);
0979     break;case IC_SUB_RET:
0980     new=__HC_ICAdd_SubRet(cc2);
0981     break;case IC_SUB_CALL:
0982     new=__HC_ICAdd_SubCall(cc2,cur->ic_data(CCodeMisc*)->addr);
0983     break;case IC_SWITCH:
0984     misc=cur->ic_data(CCodeMisc*);
0985     __HC_ICAdd_BoundedSwitch(cc2,misc->addr,misc->dft->addr);
0986     break;case IC_NOBOUND_SWITCH:
0987     __HC_ICAdd_UnboundedSwitch(cc2,cur->ic_data(CCodeMisc*)->addr);
0988     break;case IC_RET:
0989     new=__HC_ICAdd_Ret(cc2);
0990     break;case IC_CALL_INDIRECT:
0991     new=__HC_ICAdd_Call(
0992       cc2,
0993       cur->length-1,
0994       cur->ic_class->raw_type,
0995       0);
0996     /*TODO 
0997     IC_CALL
0998     IC_CALL_INDIRECT2
0999     IC_CALL_IMPORT
1000     IC_CALL_EXTERN
1001     */
1002     break;case IC_VARGS:
1003     new=__HC_ICAdd_Vargs(cc2,cur->ic_data);
1004     break;case IC_STATIC:
1005     //HolyC side accounts for the ptr arithmetic for us
1006     if(cur->last(CRPN*)->type==IC_ADDR) {
1007       new=__HC_ICAdd_StaticRef(cc2,cur->ic_data,RT_U8,0);
1008     } else if(!cur->ic_dim)
1009       new=__HC_ICAdd_StaticRef(cc2,cur->ic_data,cur->ic_class->raw_type,0);
1010     else
1011       new=__HC_ICAdd_StaticRef(cc2,cur->ic_data,cmp.internal_types[RT_I64],0);
1012     }
1013     __HC_ICSetLine(new,cur->ic_line);
1014     if(cur->ic_flags&ICF_LOCK)
1015                 __HC_ICSetLock(new);
1016   }
1017   aiwnios_dbg_info=CAlloc(8*(cc->max_line-cc->min_line+2));
1018   machine_code=__HC_Compile(acc,&idx,aiwnios_dbg_info);
1019   if(res_sz) *res_sz=idx;
1020   __HC_CodeCtrlPop(acc);
1021   if(info) {
1022     aiwnios_dbg_info[0]=machine_code;
1023     aiwnios_dbg_info[cc->max_line-cc->min_line+1]=machine_code+idx;
1024     MemCpy(info[0]->body,aiwnios_dbg_info,8*(cc->max_line-cc->min_line+2));
1025   }
1026   Free(aiwnios_dbg_info);
1027   
1028   //
1029   //Turn the CMT_HASH_ENTRY to CMT_LABEL to avoid freeing the CHash.
1030   //Things work different in AIWNIOS
1031   //
1032   // Also be sure to turn the relocations to CHashImport's
1033   //
1034   for(misc=cc->coc.coc_next_misc;misc!=&cc->coc.coc_next_misc;misc=misc->next) {
1035     if(misc->type==CMT_HASH_ENTRY) {
1036       misc->type=CMT_LABEL;
1037       //
1038       // AIWNIOS will always use IC_ADDR_IMPORT,but if we find a existing symbol
1039       //   to bind we use it's address (instead of a relocation).
1040       // So if we have relocations that aren't used (have an ->addr of INVALID_PTR)
1041       // dont add a "fill-in-later" for it
1042       //
1043       if(cc->flags&CCF_AOT_COMPILE) {
1044                 if(misc->addr!=INVALID_PTR) {
1045           //All non-imported functions are short calls
1046           if(misc->flags&CMF_SHORT_ADDR) {
1047             fill_user_data.cc=cc;
1048                         fill_user_data.cm=misc;
1049                         fill_user_data.machine_code=machine_code;
1050                         __HC_CodeMiscInterateThroughRefs(misc->addr,&AddShortReloc,&fill_user_data);
1051           } else if(IsTLSReloc(misc)) {
1052             tmpaie=CAlloc(sizeof(CAOTImportExport));
1053             tmpaie->type=IET_IMM_I64;
1054             tmpaie->str=StrNew(misc->h->str);
1055             tmpaie->rip=cc->aotc->rip+(misc->addr(U8*)-machine_code);
1056             tmpaie->offset=misc->offset;
1057             QueIns(tmpaie,cc->aot->last_ie);
1058           } else {
1059             tmpaie=CAlloc(sizeof(CAOTImportExport));
1060             tmpaie->type=IET_IMM_I64;
1061             tmpaie->str=StrNew(misc->h->str);
1062             tmpaie->rip=cc->aotc->rip+(misc->addr(U8*)-machine_code);
1063             tmpaie->offset=misc->offset;
1064             QueIns(tmpaie,cc->aot->last_ie);
1065           }
1066         }
1067       } else {
1068         if(misc->addr!=INVALID_PTR) {
1069           h=CAlloc(sizeof CHashImport);
1070           h->type=HTT_IMPORT_SYS_SYM;
1071           h->str=StrNew(misc->h->str);
1072           h->module_base=machine_code;
1073           //[reloc type 1][reloc offset 4][name?]NULL]
1074           //Nroot adds an aditional byte to specify NULL after we load the silly sauce 
1075           h->module_header_entry=CAlloc(StrLen(h->str)+5+1+1);
1076           if(IsTLSReloc(misc))
1077                         h->module_header_entry[0]=IET_IMM_I64;
1078           else 
1079                         h->module_header_entry[0]=IET_IMM_I64;
1080           h->module_header_entry[1](U32)=misc->addr(U8*)-machine_code;
1081           StrCpy(h->module_header_entry+5,h->str);
1082           HashAdd(h,Fs->hash_table);
1083         }
1084       }
1085     } else if(misc->addr!=INVALID_PTR&&misc->type==CMT_LABEL&&misc->str&&!StrNCmp("0x",misc->str,2)) {
1086       tmpabs=CAlloc(sizeof(CAOTAbsAddr));
1087       tmpabs->next=cc->aotc->abss;
1088       tmpabs->type=AAT_ADD_U64;
1089       tmpabs->rip=cc->aotc->rip+(misc->addr(U8*)-machine_code);
1090       cc->aotc->abss=tmpabs;    
1091       misc->addr(U64*)[0]=Str2I64(misc->str);
1092     } else if(misc->addr!=INVALID_PTR&&misc->type==CMT_JMP_TABLE&&cc->flags&CCF_AOT_COMPILE) {
1093       for(idx=0;idx<misc->range;idx++) {
1094         tmpabs=CAlloc(sizeof(CAOTAbsAddr));
1095         tmpabs->next=cc->aotc->abss;
1096         tmpabs->type=AAT_ADD_U64;
1097         table_ptr=misc->addr2+8*idx;
1098         *table_ptr=cc->aotc->rip+(*table_ptr-machine_code(I64));
1099         tmpabs->rip=cc->aotc->rip+((misc->addr2(U8*)+8*idx)-machine_code);
1100         cc->aotc->abss=tmpabs;  
1101       }
1102     }
1103   }
1104 
1105   //
1106   // For CAiwniosAOTBlob,Fill in the relocations
1107   //
1108   for(cur=head->last;cur!=head;cur=cur->last)  {
1109     if(cur->type==IC_ASM) {
1110 //TODO AOT
1111       JITFixupAiwniosAOTBlob(cc,cur->ic_data,cur->ic_data(CAiwniosAOTBlob*)->final_start_addr);
1112       AiwniosAOTBlobDel(cur->ic_data);
1113     }
1114   }
1115   __HC_CmpCtrlDel(acc);
1116   return machine_code;
1117 }
1118 
1119 U8 *COCCompile(CCmpCtrl *cc,I64 *_code_size,CDbgInfo **_dbg,I64 *_type) {
1120   CRPN *rpn=cc->coc.coc_head.next;
1121   if(rpn->type==IC_RET&&_type)
1122     *_type=AssignRawTypeToNode(rpn->next)->raw_type;
1123   U8 *mc=AiwniosCompile(cc,_code_size,_dbg);
1124   return mc;
1125 }
1126 
1127 /**
1128  * Has format 
1129  * if(HTT_FUN)
1130  *     FUNC_NAME(U8[])
1131  *     FUNC_FILE(U8[])
1132  *     FUNC_HELP_IDX(U8[])
1133  *     U32 s,e;
1134  *     U32 line_offsets[]
1135  *     U32 stk_size
1136  *     U32 var_cnt
1137  *          VAR_NAME(U8[])
1138  *          VAR_TYPE(U8[])
1139  *          U32 reg
1140  *          U32 offset
1141  *          U32 star_cnt
1142  *          U32 total_dim //I64 array[3][4] would have total_dim of 12
1143  *
1144  * if(HTT_HELP_FILE)
1145  *     POINTS_TO_FILE(U8[])
1146  *     HELP_IDX(U8[])
1147  * ...
1148  */
1149 I64 __DbgInfoWrite(CHashTable *h,U8 *to) {
1150   I64 i,ln,size=0,min,max;
1151   CHashSrcSym *tmph;
1152   CHashFun *,*pub_tmph;
1153   CHashClass *tmpc;
1154   CMemberLst *fun_mem;
1155   CDbgInfo *dbg_info;
1156   U32 start_ptr,cnt;
1157   U8 *src_link,buffer[1024],*bptr=&buffer;
1158   for (i=0;i<=h->mask;i++) {
1159     for(tmph=h->body[i];tmph;tmph=tmph->next) {
1160       if (tmph->src_link && !(tmph->type & (HTF_IMPORT | HTF_PRIVATE)) && (dbg_info=tmph->dbg_info)) {
1161         if((tmph->type&HTT_FUN)&&!(tmph(CHashFun*)->flags&(1<<Cf_EXTERN))) {
1162           if(to) (to+size)(I64*)[0]=tmph->type&(HTT_FUN|HTF_PUBLIC);
1163           size+=sizeof(I64);
1164           StrScan(tmph->src_link,"FL:%s,%d",&bptr,&ln);
1165           if(to) StrCpy(to+size,tmph->str);
1166           size+=StrLen(tmph->str)+1;
1167           if(to) StrCpy(to+size,buffer);
1168           size+=StrLen(buffer)+1;
1169           pub_tmph=HashFind(tmph->str,h,HTF_PUBLIC);
1170           if(pub_tmph) {
1171             if(pub_tmph->idx) {
1172               if(to) StrCpy(to+size,pub_tmph->idx);
1173               size+=StrLen(pub_tmph->idx)+1;
1174               goto wrote_help_idx;
1175             }
1176           }
1177           if(tmph->idx) {
1178             if(to) StrCpy(to+size,tmph->idx);
1179             size+=StrLen(tmph->idx)+1;
1180           } else {
1181             if(to) StrCpy(to+size,"");
1182             size+=StrLen("")+1;
1183           }
1184 wrote_help_idx:
1185           min=dbg_info->min_line;
1186           max=dbg_info->max_line;
1187           if(to) (to+size)(U32*)[0]=min;
1188           if(to) (to+size)(U32*)[1]=max;
1189           size+=2*sizeof(U32);
1190           max-=min;
1191           min-=min;
1192           start_ptr=dbg_info->body[0];
1193           for(ln=0;ln<=max+1;ln++) {
1194       if(dbg_info->body[ln]) {
1195               if(to) (to+size)(U32*)[0]=dbg_info->body[ln]-start_ptr;
1196             } else
1197               if(to) (to+size)(U32*)[0]=0;
1198       size+=4;      
1199           }
1200           if(to) (to+size)(U32*)[0]=tmph(CHashFun*)->size;
1201           size+=4;
1202           fun_mem=tmph(CHashFun*)->member_lst_and_root;
1203           for(cnt=0;fun_mem;fun_mem=fun_mem->next)
1204             cnt++;
1205           if(to) (to+size)(U32*)[0]=cnt;
1206           size+=4;
1207           fun_mem=tmph(CHashFun*)->member_lst_and_root;
1208           for(;fun_mem;fun_mem=fun_mem->next) {
1209             if(to) StrCpy(to+size,fun_mem->str);
1210             size+=StrLen(fun_mem->str)+1;
1211             tmpc=fun_mem->member_class;
1212             tmpc-=tmpc->ptr_stars_cnt;
1213             if(tmpc->str) {
1214               if(to) StrCpy(to+size,tmpc->str);
1215               size+=StrLen(tmpc->str)+1;
1216             } else {
1217               if(to) to[size]=0;
1218               size++;
1219             }
1220             if(to) (to+size)(U32*)[0]=fun_mem->reg;
1221             size+=4;
1222             if(to) (to+size)(U32*)[0]=fun_mem->offset;
1223             size+=4;
1224             if(to) (to+size)(U32*)[0]=fun_mem->member_class->ptr_stars_cnt;
1225             size+=4;
1226             if(to) (to+size)(U32*)[0]=fun_mem->dim.total_cnt;
1227             size+=4;
1228           }
1229         }
1230       } else if(tmph->type&HTT_HELP_FILE){
1231         if(to) (to+size)(I64*)[0]=HTT_HELP_FILE;
1232         size+=sizeof(I64);
1233         if(to) StrCpy(to+size,tmph->str);
1234         size+=StrLen(tmph->str)+1;
1235         if(to) StrCpy(to+size,tmph->idx);
1236         size+=StrLen(tmph->idx)+1;
1237       }
1238   }
1239   }
1240   return size;
1241 }
1242 U0 DbgInfoWrite(CHashTable *h,U8 *name) {
1243         I64 len=__DbgInfoWrite(h,NULL);
1244         U8 *buf=MAlloc(len);
1245         __DbgInfoWrite(h,buf);
1246         FileWrite(name,buf,len);
1247         Free(buf);
1248 }
1249 U0 DbgInfoRead(U8 *name) {
1250   I64 len,min,max,ln,type;
1251   CHashSrcSym *tmph;
1252   CMemberLst *tmpm=NULL,*tmpm2=NULL,*tmpm_start;
1253   CDbgInfo *dbg_info;
1254   CHashClass *tmpc;
1255   U8 *body=FileRead(name,&len),*ptr=body,*fn,*idx;
1256   while(ptr<body+len) {
1257     type=ptr(I64*)[0];
1258     ptr+=8;
1259     if(type&HTT_FUN) {
1260       tmph=HashFind(ptr,Fs->hash_table,HTT_FUN);
1261       ptr+=StrLen(ptr)+1;
1262       fn=ptr;
1263       ptr+=StrLen(ptr)+1;
1264       idx=ptr;
1265       ptr+=StrLen(ptr)+1;
1266       min=ptr(U32*)[0];
1267       max=ptr(U32*)[1];
1268       ptr+=2*sizeof(U32);
1269       if(tmph&&tmph->type&HTT_FUN) {
1270         tmph->type|=type; //type may include HTF_PUBLIC
1271         Free(tmph->src_link);
1272         Free(tmph->idx);
1273         if(StrLen(idx))
1274           tmph->idx=StrNew(idx);
1275         else
1276           tmph->idx=NULL;
1277         tmph->src_link=MStrPrint("FL:%s,%d",fn,min);
1278         tmph->dbg_info=CAlloc(sizeof(CDbgInfo)+sizeof(I64)*(max-min+1));
1279         tmph->dbg_info->min_line=min;
1280         tmph->dbg_info->max_line=max;
1281         for(ln=min;ln<=max+1;ln++) {
1282           tmph->dbg_info->body[ln-min]=tmph(CHashFun*)->exe_addr(U8*)+ptr(U32*)[ln-min];
1283           if(ln-min&&tmph->dbg_info->body[ln-min]==tmph(CHashFun*)->exe_addr)
1284             tmph->dbg_info->body[ln-min]=NULL;
1285         }
1286       }
1287       ptr+=sizeof(U32)*(max-min+1+1);
1288       if(tmph) tmph(CHashFun*)->size=ptr(I32*)[0];
1289       ptr+=sizeof(U32);
1290       max=ptr(U32*)[0];
1291       ptr+=sizeof(U32);
1292       tmpm=NULL;
1293       tmpm2=NULL;
1294       tmpm_start=NULL;
1295       for(min=0;min!=max;min++) {
1296         if(tmph) tmpm=CAlloc(sizeof(CMemberLst));
1297         if(tmph) tmpm->str=StrNew(ptr);
1298         ptr+=StrLen(ptr)+1;
1299         tmpc=HashFind(ptr,Fs->hash_table,HTT_CLASS|HTT_INTERNAL_TYPE);
1300         if(tmph) tmpm->member_class=tmpc;
1301         ptr+=StrLen(ptr)+1;
1302         //If we couldn't find a class,continue
1303         if(!tmpc) {
1304           if(tmpm) Free(tmpm->str);
1305           Free(tmpm);
1306           ptr+=16;
1307           goto next;
1308         } 
1309         if(tmph) tmpm->reg=ptr(U32*)[0];
1310         ptr+=4;
1311         if(tmph) tmpm->offset=ptr(I32*)[0];
1312         ptr+=4;
1313         if(tmpm) tmpm->member_class+=ptr(U32*)[0]; //In TempleOS,the next class is a "pointer star"
1314         ptr+=4;
1315         if(tmpm) tmpm->dim.total_cnt=tmpm->dim.cnt=ptr(U32*)[0];
1316         ptr+=4;
1317         if(!tmpm_start) tmpm_start=tmpm;
1318         if(tmpm2) tmpm2->next=tmpm;
1319         tmpm2=tmpm;
1320         next:;
1321       }
1322       if(tmph) {
1323         tmpm=tmph(CHashFun*)->member_lst_and_root;
1324         for(;tmpm&&tmpm->next;tmpm=tmpm->next);
1325         if(tmpm)
1326           tmpm->next=tmpm_start;
1327         else
1328           tmph(CHashFun*)->member_lst_and_root=tmpm_start;
1329       }
1330     } else if(type&HTT_HELP_FILE) {
1331       tmph=CAlloc(sizeof(CHashSrcSym));
1332       tmph->type=HTF_PUBLIC|HTT_HELP_FILE;
1333       tmph->str=StrNew(ptr);
1334       ptr+=StrLen(ptr)+1;
1335       tmph->idx=StrNew(ptr);
1336       ptr+=StrLen(ptr)+1;
1337       HashAdd(tmph,Fs->hash_table);
1338     }
1339   }
1340   Free(body);
1341 }
1342