Fixing generation of arithmetic expressions:
[dyninst.git] / dyninstAPI / src / inst-aarch64.C
1 /*
2  * See the dyninst/COPYRIGHT file for copyright information.
3  *
4  * We provide the Paradyn Tools (below described as "Paradyn")
5  * on an AS IS basis, and do not warrant its validity or performance.
6  * We reserve the right to update, modify, or discontinue this
7  * software at any time.  We shall have no obligation to supply such
8  * updates or modifications or any other form of support to you.
9  *
10  * By your use of Paradyn, you understand and agree that we (or any
11  * other person or entity with proprietary rights in Paradyn) are
12  * under no obligation to provide either maintenance services,
13  * update services, notices of latent defects, or correction of
14  * defects for Paradyn.
15  *
16  * This library is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU Lesser General Public
18  * License as published by the Free Software Foundation; either
19  * version 2.1 of the License, or (at your option) any later version.
20  *
21  * This library is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24  * Lesser General Public License for more details.
25  *
26  * You should have received a copy of the GNU Lesser General Public
27  * License along with this library; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29  */
30
31 //#warning "This file is not implemented yet!"
32
33 #include "common/src/headers.h"
34 #include "dyninstAPI/h/BPatch_memoryAccess_NP.h"
35 #include "dyninstAPI/src/image.h"
36 #include "dyninstAPI/src/dynProcess.h"
37 #include "dyninstAPI/src/inst.h"
38 #include "dyninstAPI/src/instP.h"
39 #include "dyninstAPI/src/inst-aarch64.h"
40 #include "common/src/arch.h"
41 #include "dyninstAPI/src/codegen.h"
42 #include "dyninstAPI/src/ast.h"
43 #include "dyninstAPI/src/util.h"
44 #include "common/src/stats.h"
45 #include "dyninstAPI/src/os.h"
46 #include "dyninstAPI/src/instPoint.h" // class instPoint
47 #include "dyninstAPI/src/debug.h"
48 #include "common/src/debugOstream.h"
49 #include "dyninstAPI/src/baseTramp.h"
50 #include "dyninstAPI/h/BPatch.h"
51 #include "dyninstAPI/src/BPatch_collections.h"
52 #include "dyninstAPI/src/registerSpace.h"
53 #include "dyninstAPI/src/binaryEdit.h"
54 #include "dyninstAPI/src/function.h"
55 #include "dyninstAPI/src/mapped_object.h"
56
57 #include "parseAPI/h/CFG.h"
58
59 #include "emitter.h"
60 #include "emit-aarch64.h"
61
62 #include <boost/assign/list_of.hpp>
63 using namespace boost::assign;
64 #include <sstream>
65
66 #include "dyninstAPI/h/BPatch_memoryAccess_NP.h"
67
68 extern bool isPowerOf2(int value, int &result);
69
70 #define DISTANCE(x, y)   ((x<y) ? (y-x) : (x-y))
71
72 Address getMaxBranch() {
73     return MAX_BRANCH_OFFSET;
74 }
75
76 std::unordered_map<std::string, unsigned> funcFrequencyTable;
77
78 void initDefaultPointFrequencyTable() {
79     assert(0); //Not implemented
80 }
81
82 /************************************* Register Space **************************************/
83
84 void registerSpace::initialize32() {
85     assert(!"No 32-bit implementation for the ARM architecture!");
86 }
87
88 void registerSpace::initialize64() {
89     static bool done = false;
90     if (done)
91         return;
92
93     pdvector < registerSlot * > registers;
94
95     //GPRs
96     for (unsigned idx = r0; idx <= r28; idx++) {
97         char name[32];
98         if (idx < 10)
99             sprintf(name, "r%1d", idx - r0);
100         else
101             sprintf(name, "r%2d", idx - r0);
102         registers.push_back(new registerSlot(idx,
103                                              name,
104                                              false,
105                                              registerSlot::liveAlways,
106                                              registerSlot::GPR));
107     }
108     //Mark r29 (frame pointer) and r30 (link register) as off-limits
109     registers.push_back(new registerSlot(r29, "r29", true, registerSlot::liveAlways, registerSlot::GPR));
110     registers.push_back(new registerSlot(r30, "r30", true, registerSlot::liveAlways, registerSlot::GPR));
111
112     //SPRs
113     registers.push_back(new registerSlot(lr, "lr", true, registerSlot::liveAlways, registerSlot::SPR));
114     registers.push_back(new registerSlot(sp, "sp", true, registerSlot::liveAlways, registerSlot::SPR));
115     registers.push_back(new registerSlot(pstate, "nzcv", true, registerSlot::liveAlways, registerSlot::SPR));
116     registers.push_back(new registerSlot(fpcr, "fpcr", true, registerSlot::liveAlways, registerSlot::SPR));
117     registers.push_back(new registerSlot(fpsr, "fpsr", true, registerSlot::liveAlways, registerSlot::SPR));
118
119     //FPRs
120     for (unsigned idx = fpr0; idx <= fpr31; idx++) {
121         char name[32];
122         sprintf(name, "fpr%d", idx - fpr0);
123         registers.push_back(new registerSlot(idx,
124                                              name,//TODO mov SP to FP
125                                              false,
126                                              registerSlot::liveAlways,
127                                              registerSlot::FPR));
128     }
129
130     registerSpace::createRegisterSpace64(registers);
131     done = true;
132 }
133
134 void registerSpace::initialize() {
135     initialize64();
136 }
137
138 /************************************************************************************************/
139 /************************************************************************************************/
140
141 /********************************* EmitterAARCH64SaveRegs ***************************************/
142
143 /********************************* Private methods *********************************************/
144
145 void EmitterAARCH64SaveRegs::saveSPR(codeGen &gen, Register scratchReg, int sprnum, int stkOffset)
146 {
147     assert(scratchReg!=REG_NULL);
148
149     //TODO move map to common location
150     map<int, int> sysRegCodeMap = map_list_of(SPR_NZCV, 0x5A10)(SPR_FPCR, 0x5A20)(SPR_FPSR, 0x5A21);
151     if(!sysRegCodeMap.count(sprnum))
152         assert(!"Invalid/unknown system register passed to saveSPR()!");
153
154     instruction insn;
155     insn.clear();
156
157     //Set opcode for MRS instruction
158     INSN_SET(insn, 20, 31, MRSOp);
159     //Set destination register
160     INSN_SET(insn, 0, 4, scratchReg & 0x1F);
161     //Set bits representing source system register
162     INSN_SET(insn, 5, 19, sysRegCodeMap[sprnum]);
163     insnCodeGen::generate(gen, insn);
164
165     insnCodeGen::generateMemAccess32or64(gen, insnCodeGen::Store, scratchReg,
166             REG_SP, stkOffset, false, insnCodeGen::Pre);
167 }
168
169 void EmitterAARCH64SaveRegs::saveRegister(codeGen &gen, Register reg, int save_off)
170 {
171     insnCodeGen::generateMemAccess32or64(gen, insnCodeGen::Store, reg, REG_SP,
172             -2*GPRSIZE_64, true, insnCodeGen::Pre);
173 }
174
175
176 void EmitterAARCH64SaveRegs::saveFPRegister(codeGen &gen, Register reg, int save_off) {
177     //Always performing save of the full FP register
178     insnCodeGen::generateMemAccessFP(gen, insnCodeGen::Store, reg, REG_SP, save_off, 0, true);
179
180 }
181
182 /********************************* Public methods *********************************************/
183
184 unsigned EmitterAARCH64SaveRegs::saveGPRegisters(
185         baseTramp *bt, codeGen &gen, registerSpace *theRegSpace, int &offset, int numReqGPRs)
186 {
187     int ret = 0;
188     if(numReqGPRs == -1)
189         numReqGPRs = theRegSpace->numGPRs();
190
191     pdvector<registerSlot *> &regs = theRegSpace->trampRegs();
192
193     for(unsigned int idx = 0; idx < regs.size() && ret < numReqGPRs; idx++) {
194         registerSlot *reg = regs[idx];
195         if (reg->liveState == registerSlot::live) {
196             saveRegister(gen, reg->number, offset);
197             theRegSpace->markSavedRegister(reg->number, offset);
198
199             offset += 2*GPRSIZE_64;
200             ret++;
201         }
202     }
203
204     return ret;
205 }
206
207 unsigned EmitterAARCH64SaveRegs::saveFPRegisters(codeGen &gen, registerSpace *theRegSpace, int &offset) {
208     unsigned ret = 0;
209
210     for(int idx = 0; idx < theRegSpace->numFPRs(); idx++) {
211         registerSlot *reg = theRegSpace->FPRs()[idx];
212
213         if(reg->liveState == registerSlot::live) {
214             saveFPRegister(gen, reg->number, -8*FPRSIZE);
215             reg->liveState = registerSlot::spilled;
216
217             offset += 8*FPRSIZE;
218             ret++;
219         }
220     }
221
222     return ret;
223 }
224
225 unsigned EmitterAARCH64SaveRegs::saveSPRegisters(
226         codeGen &gen, registerSpace *theRegSpace, int &offset, bool force_save)
227 {
228     int ret = 0;
229
230     pdvector<registerSlot *> spRegs;
231     map<registerSlot *, int> regMap;
232
233     registerSlot *regNzcv = (*theRegSpace)[registerSpace::pstate];
234     assert(regNzcv);
235     regMap[regNzcv] = SPR_NZCV;
236     if(force_save || regNzcv->liveState == registerSlot::live)
237         spRegs.push_back(regNzcv);
238
239     registerSlot *regFpcr = (*theRegSpace)[registerSpace::fpcr];
240     assert(regFpcr);
241     regMap[regFpcr] = SPR_FPCR;
242     if(force_save || regFpcr->liveState == registerSlot::live)
243         spRegs.push_back(regFpcr);
244
245     registerSlot *regFpsr = (*theRegSpace)[registerSpace::fpsr];
246     assert(regFpsr);
247     regMap[regFpsr] = SPR_FPSR;
248     if(force_save || regFpsr->liveState == registerSlot::live)
249         spRegs.push_back(regFpsr);
250
251     for(pdvector<registerSlot *>::iterator itr = spRegs.begin(); itr != spRegs.end(); itr++) {
252         registerSlot *cur = *itr;
253         saveSPR(gen, theRegSpace->getScratchRegister(gen, true), regMap[cur], -4*GPRSIZE_32);
254         theRegSpace->markSavedRegister(cur->number, offset);
255
256         offset += 4*GPRSIZE_32;
257         ret++;
258     }
259
260     return ret;
261 }
262
263 void EmitterAARCH64SaveRegs::createFrame(codeGen &gen) {
264     //Save link register
265     Register linkRegister = gen.rs()->getRegByName("r30");
266     saveRegister(gen, linkRegister, -2*GPRSIZE_64);
267
268     //Save frame pointer
269     Register framePointer = gen.rs()->getRegByName("r29");
270     saveRegister(gen, framePointer, -2*GPRSIZE_64);
271
272     //Move stack pointer to frame pointer
273     Register stackPointer = gen.rs()->getRegByName("sp");
274     insnCodeGen::generateMoveSP(gen, stackPointer, framePointer, true);
275 }
276
277 /***********************************************************************************************/
278 /***********************************************************************************************/
279
280 /********************************* EmitterAARCH64RestoreRegs ************************************/
281
282 /********************************* Public methods *********************************************/
283
284 unsigned EmitterAARCH64RestoreRegs::restoreGPRegisters(
285         codeGen &gen, registerSpace *theRegSpace)
286 {
287     unsigned ret = 0;
288
289     for(int idx = theRegSpace->numGPRs()-1; idx >=0; idx--) {
290         registerSlot *reg = theRegSpace->GPRs()[idx];
291
292         if(reg->liveState == registerSlot::spilled) {
293             restoreRegister(gen, reg->number, 2*GPRSIZE_64);
294             ret++;
295         }
296     }
297
298     return ret;
299 }
300
301 unsigned EmitterAARCH64RestoreRegs::restoreFPRegisters(
302         codeGen &gen, registerSpace *theRegSpace)
303 {
304     unsigned ret = 0;
305
306     for(int idx = theRegSpace->numFPRs() - 1; idx >= 0; idx--) {
307         registerSlot *reg = theRegSpace->FPRs()[idx];
308
309         if(reg->liveState == registerSlot::spilled) {
310             restoreFPRegister(gen, reg->number, 8*FPRSIZE);
311             ret++;
312         }
313     }
314
315     return ret;
316 }
317
318 unsigned EmitterAARCH64RestoreRegs::restoreSPRegisters(
319         codeGen &gen, registerSpace *theRegSpace, int force_save)
320 {
321     int ret = 0;
322
323     pdvector<registerSlot *> spRegs;
324     map<registerSlot *, int> regMap;
325
326     registerSlot *regNzcv = (*theRegSpace)[registerSpace::pstate];
327     assert(regNzcv);
328     regMap[regNzcv] = SPR_NZCV;
329     if(force_save || regNzcv->liveState == registerSlot::spilled)
330         spRegs.push_back(regNzcv);
331
332     registerSlot *regFpcr = (*theRegSpace)[registerSpace::fpcr];
333     assert(regFpcr);
334     regMap[regFpcr] = SPR_FPCR;
335     if(force_save || regFpcr->liveState == registerSlot::spilled)
336         spRegs.push_back(regFpcr);
337
338     registerSlot *regFpsr = (*theRegSpace)[registerSpace::fpsr];
339     assert(regFpsr);
340     regMap[regFpsr] = SPR_FPSR;
341     if(force_save || regFpsr->liveState == registerSlot::spilled)
342         spRegs.push_back(regFpsr);
343
344     for(pdvector<registerSlot *>::iterator itr = spRegs.begin(); itr != spRegs.end(); itr++) {
345         registerSlot *cur = *itr;
346         restoreSPR(gen, theRegSpace->getScratchRegister(gen, true), regMap[cur], 4*GPRSIZE_32);
347         ret++;
348     }
349
350     return ret;
351 }
352
353 void EmitterAARCH64RestoreRegs::tearFrame(codeGen &gen) {
354     //Restore frame pointer
355     Register framePointer = gen.rs()->getRegByName("r29");
356     restoreRegister(gen, framePointer, 2*GPRSIZE_64);
357
358     //Restore link register
359     Register linkRegister = gen.rs()->getRegByName("r30");
360     restoreRegister(gen, linkRegister, 2*GPRSIZE_64);
361 }
362
363
364 /********************************* Private methods *********************************************/
365
366 void EmitterAARCH64RestoreRegs::restoreSPR(codeGen &gen, Register scratchReg, int sprnum, int stkOffset)
367 {
368     insnCodeGen::generateMemAccess32or64(gen, insnCodeGen::Load, scratchReg, REG_SP, stkOffset, false);
369
370     //TODO move map to common location
371     map<int, int> sysRegCodeMap = map_list_of(SPR_NZCV, 0x5A10)(SPR_FPCR, 0x5A20)(SPR_FPSR, 0x5A21);
372     if (!sysRegCodeMap.count(sprnum))
373         assert(!"Invalid/unknown system register passed to restoreSPR()!");
374
375     instruction insn;
376     insn.clear();
377
378     //Set opcode for MSR (register) instruction
379     INSN_SET(insn, 20, 31, MSROp);
380     //Set source register
381     INSN_SET(insn, 0, 4, scratchReg & 0x1F);
382     //Set bits representing destination system register
383     INSN_SET(insn, 5, 19, sysRegCodeMap[sprnum]);
384     insnCodeGen::generate(gen, insn);
385 }
386
387 void EmitterAARCH64RestoreRegs::restoreRegister(codeGen &gen, Register reg, int save_off) {
388
389     insnCodeGen::generateMemAccess32or64(gen, insnCodeGen::Load, reg, REG_SP,
390             2*GPRSIZE_64, true);
391 }
392
393 void EmitterAARCH64RestoreRegs::restoreFPRegister(codeGen &gen, Register reg, int save_off) {
394     insnCodeGen::generateMemAccessFP(gen, insnCodeGen::Load, reg, REG_SP, save_off, 0, true);
395 }
396
397 /***********************************************************************************************/
398 /***********************************************************************************************/
399
400 /*********************************** Base Tramp ***********************************************/
401 bool baseTramp::generateSaves(codeGen &gen, registerSpace *)
402 {
403     EmitterAARCH64SaveRegs saveRegs;
404
405     int offset = 0;
406
407     baseTramp *bt = this;
408     bool saveFrame = !bt || bt->needsFrame();
409     if(saveFrame) {
410         saveRegs.createFrame(gen);
411         offset += (GPRSIZE_64 * 2);
412     }
413     bt->createdFrame = saveFrame;
414     /* print LSB to MSB, in order */
415     auto prinDefined = [&](){
416         for (boost::dynamic_bitset<>::size_type i = 0;
417                 i < bt->definedRegs.size(); ++i)
418         {
419             std::cerr << bt->definedRegs[i];
420         }
421         std::cerr << "\tsize = " << bt->definedRegs.size();
422         std::cerr << "\tnone = " << bt->definedRegs.none();
423         std::cerr << "\tany  = " << bt->definedRegs.any();
424         std::cerr << std::endl;
425     };
426     //prinDefined();
427     bt->definedRegs = gen.getRegsDefined();
428     //prinDefined();
429     assert(!bt->definedRegs.empty());
430
431     saveRegs.saveGPRegisters(bt, gen, gen.rs(), offset);
432
433     bool saveFPRs = BPatch::bpatch->isForceSaveFPROn() ||
434                    (BPatch::bpatch->isSaveFPROn()      &&
435                     gen.rs()->anyLiveFPRsAtEntry()     &&
436                     bt->saveFPRs());
437
438     if(saveFPRs)
439         saveRegs.saveFPRegisters(gen, gen.rs(), offset);
440     bt->savedFPRs = saveFPRs;
441
442     saveRegs.saveSPRegisters(gen, gen.rs(), offset, false);
443     //gen.rs()->debugPrint();
444
445     return true;
446 }
447
448 bool baseTramp::generateRestores(codeGen &gen, registerSpace *)
449 {
450     EmitterAARCH64RestoreRegs restoreRegs;
451
452     restoreRegs.restoreSPRegisters(gen, gen.rs(), false);
453
454     baseTramp *bt = this;
455     if(bt->savedFPRs)
456         restoreRegs.restoreFPRegisters(gen, gen.rs());
457
458     restoreRegs.restoreGPRegisters(gen, gen.rs());
459
460     if(bt->createdFrame)
461         restoreRegs.tearFrame(gen);
462
463     return true;
464 }
465
466 /***********************************************************************************************/
467 /***********************************************************************************************/
468
469 //TODO: 32-/64-bit regs?
470 void emitImm(opCode op, Register src1, RegValue src2imm, Register dest, 
471         codeGen &gen, bool /*noCost*/, registerSpace * /* rs */)
472 {
473     switch(op) {
474         case plusOp:
475         case minusOp:
476             {
477                 if(src2imm >= -(1 << 11) && src2imm < (long int)((1 << 11) - 1))
478                     insnCodeGen::generateAddSubImmediate(gen,
479                             op == plusOp ? insnCodeGen::Add : insnCodeGen::Sub, 0,
480                             src2imm, src1, dest, false);
481                 else if(src2imm >= MIN_IMM16 && src2imm < MAX_IMM16)
482                 {
483                     Register rm = insnCodeGen::moveValueToReg(gen, src2imm);
484                     insnCodeGen::generateAddSubShifted(gen,
485                             op == plusOp ? insnCodeGen::Add : insnCodeGen::Sub,
486                             0, 0, rm, src1, dest, true);
487                 }
488             }
489             break;
490         case timesOp:
491             {
492                 Register rm = insnCodeGen::moveValueToReg(gen, src2imm);
493                 insnCodeGen::generateMul(gen, rm, src1, dest, true);
494             }
495             break;
496         case divOp:
497             {
498                 Register rm = insnCodeGen::moveValueToReg(gen, src2imm);
499                 insnCodeGen::generateDiv(gen, rm, src1, dest, true);
500             }
501             break;
502         case orOp:
503             {
504                 Register rm = insnCodeGen::moveValueToReg(gen, src2imm);
505                 insnCodeGen::generateBitwiseOpShifted(gen, insnCodeGen::Or, 0, rm, 0, src1, dest, true);
506             }
507             break;
508         case andOp:
509             {
510                 Register rm = insnCodeGen::moveValueToReg(gen, src2imm);
511                 insnCodeGen::generateBitwiseOpShifted(gen, insnCodeGen::And, 0, rm, 0, src1, dest, true);
512             }
513             break;
514         case eqOp:
515             {
516                 Register scratch = gen.rs()->getScratchRegister(gen);
517                 emitVload(loadConstOp, src2imm, NULL, scratch, gen, true);
518                 emitV(op, src1, scratch, dest, gen, true);
519             }
520             break;
521         default:
522             assert(0); // not implemented or not valid
523             break;
524     }
525 }
526
527 void cleanUpAndExit(int status);
528
529 /* Recursive function that goes to where our instrumentation is calling
530 to figure out what registers are clobbered there, and in any function
531 that it calls, to a certain depth ... at which point we clobber everything
532
533 Update-12/06, njr, since we're going to a cached system we are just going to
534 look at the first level and not do recursive, since we would have to also
535 store and reexamine every call out instead of doing it on the fly like before*/
536 bool EmitterAARCH64::clobberAllFuncCall(registerSpace *rs,
537                                         func_instance *callee) {
538     if(!callee)
539         return true;
540
541     stats_codegen.startTimer(CODEGEN_LIVENESS_TIMER);
542
543     if(callee->ifunc()->isLeafFunc()) {
544         std::set<Register> *gpRegs = callee->ifunc()->usedGPRs();
545         for(std::set<Register>::iterator itr = gpRegs->begin(); itr != gpRegs->end(); itr++)
546             rs->GPRs()[*itr]->beenUsed = true;
547
548         std::set<Register> *fpRegs = callee->ifunc()->usedFPRs();
549         for(std::set<Register>::iterator itr = fpRegs->begin(); itr != fpRegs->end(); itr++)
550             rs->FPRs()[*itr]->beenUsed = true;
551     } else {
552         for(int idx = 0; idx < rs->numGPRs(); idx++)
553             rs->GPRs()[idx]->beenUsed = true;
554         for(int idx = 0; idx < rs->numFPRs(); idx++)
555             rs->FPRs()[idx]->beenUsed = true;
556     }
557
558     stats_codegen.stopTimer(CODEGEN_LIVENESS_TIMER);
559
560     return false;
561 }
562
563 Register emitFuncCall(opCode, codeGen &, pdvector <AstNodePtr> &, bool, Address) {
564     assert(0);
565     return 0;
566 }
567
568 Register emitFuncCall(opCode op,
569                       codeGen &gen,
570                       pdvector <AstNodePtr> &operands, bool noCost,
571                       func_instance *callee) {
572     return gen.emitter()->emitCall(op, gen, operands, noCost, callee);
573 }
574
575 Register EmitterAARCH64::emitCallReplacement(opCode ocode,
576                                              codeGen &gen,
577                                              bool /* noCost */,
578                                              func_instance *callee) {
579     assert(0); //Not implemented
580     return 0;
581 }
582
583 // There are four "axes" going on here:
584 // 32 bit vs 64 bit
585 // Instrumentation vs function call replacement
586 // Static vs. dynamic
587
588 Register EmitterAARCH64::emitCall(opCode op,
589                                   codeGen &gen,
590                                   const std::vector<AstNodePtr> &operands,
591                                   bool noCost,
592                                   func_instance *callee) 
593 {
594     //#sasha This function implementation is experimental.
595
596     if (op != callOp) {
597         cerr << "ERROR: emitCall with op == " << op << endl;
598     }
599     assert(op == callOp);
600
601     std::vector<Register> srcs;
602     std::vector<Register> saves;
603
604     //  Sanity check for NULL address arg
605     if (!callee) 
606     {
607         char msg[256];
608         sprintf(msg, "%s[%d]:  internal error:  emitFuncCall called w/out"
609                 "callee argument", __FILE__, __LINE__);
610         showErrorCallback(80, msg);
611         assert(0);
612     }
613
614     vector<int> savedRegs;
615
616     // save r0-r7
617     for(size_t id = 0; id < gen.rs()->numGPRs(); id++)
618     {
619         registerSlot *reg = gen.rs()->GPRs()[id];
620
621         // We must save if:
622         // refCount > 0 (and not a source register)
623         // keptValue == true (keep over the call)
624         // liveState == live (technically, only if not saved by the callee)
625
626         if ((reg->refCount > 0) || reg->keptValue || (reg->liveState == registerSlot::live))
627         {
628             insnCodeGen::saveRegister(gen, registerSpace::r0 + id);
629             savedRegs.push_back(reg->number);
630         }
631     }
632
633     // Passing operands to registers
634     for(size_t id = 0; id < operands.size(); id++)
635     {
636         Register reg = REG_NULL;
637         if (gen.rs()->allocateSpecificRegister(gen, registerSpace::r0 + id, true))
638             reg = registerSpace::r0 + id;
639
640         Address unnecessary = ADDR_NULL;
641         if (!operands[id]->generateCode_phase2(gen, false, unnecessary, reg))
642             assert(0);
643         assert(reg!=REG_NULL);
644     }
645
646     //instPoint *point = gen.point();
647     //assert(point);
648     assert(gen.rs());
649
650     //Address of function to call in scratch register
651     Register scratch = gen.rs()->getScratchRegister(gen);
652     assert(scratch!=REG_NULL);
653     insnCodeGen::loadImmIntoReg<Address>(gen, scratch, callee->addr());
654
655     instruction branchInsn;
656     branchInsn.clear();
657
658     //Set bits which are 0 for both BR and BLR
659     INSN_SET(branchInsn, 0, 4, 0);
660     INSN_SET(branchInsn, 10, 15, 0);
661
662     //Set register
663     INSN_SET(branchInsn, 5, 9, scratch);
664
665     //Set other bits. Basically, these are the opcode bits.
666     //The only difference between BR and BLR is that bit 21 is 1 for BLR.
667     INSN_SET(branchInsn, 16, 31, BRegOp);
668     INSN_SET(branchInsn, 21, 21, 1);
669     insnCodeGen::generate(gen, branchInsn);
670
671     /*
672      * Restoring registers
673      */
674
675     // r7-r0
676     for (signed int ui = savedRegs.size()-1; ui >= 0; ui--) {
677         insnCodeGen::restoreRegister(gen, registerSpace::r0 + savedRegs[ui]);
678     }
679
680     return 0;
681 }
682
683
684 codeBufIndex_t emitA(opCode op, Register src1, Register src2, long dest,
685         codeGen &gen, RegControl rc, bool noCost)
686 {
687     codeBufIndex_t retval = 0;
688
689     switch (op) {
690         case ifOp: 
691             {
692                 // if src1 == 0 jump to dest
693                 // src1 is a temporary
694                 // dest is a target address
695                 retval = gen.codeEmitter()->emitIf(src1, dest, rc, gen);
696                 break;
697             }
698         default:
699             assert(0);        // op not implemented or not expected for this emit!
700     }
701
702     return retval;
703 }
704
705 Register emitR(opCode op, Register src1, Register src2, Register dest,
706                codeGen &gen, bool /*noCost*/,
707                const instPoint * location, bool /*for_MT*/)
708 {
709     registerSlot *regSlot = NULL;
710
711     switch(op){
712         case getParamOp:
713             // src1 is the number of the argument
714             // dest is a register where we can store the value
715             //gen.codeEmitter()->emitGetParam(dest, src1, location->type(), op,
716             //        false, gen);
717
718             if(src1 <= 3) {
719                 // src1 is 0..8 - it's a parameter number, not a register
720                 regSlot = (*(gen.rs()))[registerSpace::r0 + src1];
721                 break;
722
723             } else {
724                 assert(0);
725             }
726             break;
727         default:
728             assert(0);
729     }
730     assert(regSlot);
731     Register reg = regSlot->number;
732
733     return reg;
734 }
735
736 void emitJmpMC(int /*condition*/, int /*offset*/, codeGen &) {
737     assert(0); //Not implemented
738     // Not needed for memory instrumentation, otherwise TBD
739 }
740
741
742 // VG(11/16/01): Say if we have to restore a register to get its original value
743 // VG(03/15/02): Sync'd with the new AIX tramp
744 static inline bool needsRestore(Register x) {
745     assert(0); //Not implemented
746     return false;
747 }
748
749 // VG(03/15/02): Restore mutatee value of GPR reg to dest GPR
750 static inline void restoreGPRtoGPR(codeGen &gen,
751                                    Register reg, Register dest) {
752     assert(0); //Not implemented
753 }
754
755 // VG(03/15/02): Restore mutatee value of XER to dest GPR
756 static inline void restoreXERtoGPR(codeGen &gen, Register dest) {
757     assert(0); //Not implemented
758 }
759
760 // VG(03/15/02): Move bits 25:31 of GPR reg to GPR dest
761 static inline void moveGPR2531toGPR(codeGen &gen,
762                                     Register reg, Register dest) {
763     assert(0); //Not implemented
764 }
765
766 // VG(11/16/01): Emit code to add the original value of a register to
767 // another. The original value may need to be restored from stack...
768 // VG(03/15/02): Made functionality more obvious by adding the above functions
769 static inline void emitAddOriginal(Register src, Register acc,
770                                    codeGen &gen, bool noCost) {
771     assert(0); //Not implemented
772 }
773
774 // VG(11/07/01): Load in destination the effective address given
775 // by the address descriptor. Used for memory access stuff.
776 void emitASload(const BPatch_addrSpec_NP *as, Register dest, int stackShift,
777                 codeGen &gen,
778                 bool noCost) {
779     assert(0); //Not implemented
780 }
781
782 void emitCSload(const BPatch_addrSpec_NP *as, Register dest, codeGen &gen,
783                 bool noCost) {
784     assert(0); //Not implemented
785 }
786
787 void emitVload(opCode op, Address src1, Register src2, Register dest,
788                codeGen &gen, bool /*noCost*/,
789                registerSpace * /*rs*/, int size,
790                const instPoint * /* location */, AddressSpace *proc)
791 {
792     switch(op)
793     {
794         case loadConstOp:
795             // dest is a temporary
796             // src1 is an immediate value
797             // dest = src1:imm32
798             gen.codeEmitter()->emitLoadConst(dest, src1, gen);
799             break;
800         case loadOp:
801             // dest is a temporary
802             // src1 is the address of the operand
803             // dest = [src1]
804             gen.codeEmitter()->emitLoad(dest, src1, size, gen);
805             break;
806         default:
807             assert(0); //Not implemented
808             break;
809     }
810 }
811
812 void emitVstore(opCode op, Register src1, Register /*src2*/, Address dest,
813                 codeGen &gen, bool noCost,
814                 registerSpace * /* rs */, int size,
815                 const instPoint * /* location */, AddressSpace *proc)
816 {
817     if (op ==  storeOp) {
818         // [dest] = src1
819         // dest has the address where src1 is to be stored
820         // src1 is a temporary
821         // src2 is a "scratch" register, we don't need it in this architecture
822         gen.codeEmitter()->emitStore(dest, src1, size, gen);
823     }else{
824         assert(0); //Not implemented
825     }
826     return;
827 }
828
829 void emitV(opCode op, Register src1, Register src2, Register dest,
830            codeGen &gen, bool /*noCost*/,
831            registerSpace * /*rs*/, int size,
832            const instPoint * /* location */, AddressSpace *proc) 
833 {
834     switch(op){
835         case plusOp:
836         case minusOp:
837         case divOp:
838         case timesOp:
839         case orOp:
840         case andOp:
841             gen.codeEmitter()->emitOp(op, dest, src1, src2, gen);
842             break;
843         case lessOp:
844         case leOp:
845         case greaterOp:
846         case geOp:
847         case eqOp:
848         case neOp:
849             gen.codeEmitter()->emitRelOp(op, dest, src1, src2, gen);
850             break;
851         default:
852             //std::cout << "operation= " << op << endl;
853             assert(0); // Not implemented
854             break;
855     }
856     return;
857 }
858
859 //
860 // I don't know how to compute cycles for AARCH64 instructions due to
861 //   multiple functional units.  However, we can compute the number of
862 //   instructions and hope that is fairly close. - jkh 1/30/96
863 //
864 int getInsnCost(opCode op) {
865     assert(0); //Not implemented
866     return NULL;
867 }
868
869 #if 0
870 // What does this do???
871 void registerSpace::saveClobberInfo(const instPoint *location)
872 {
873   registerSlot *regSlot = NULL;
874   registerSlot *regFPSlot = NULL;
875   if (location == NULL)
876     return;
877   if (location->actualGPRLiveSet_ != NULL && location->actualFPRLiveSet_ != NULL)
878     {
879
880       // REG guard registers, if live, must be saved
881       if (location->actualGPRLiveSet_[ REG_GUARD_ADDR ] == LIVE_REG)
882     location->actualGPRLiveSet_[ REG_GUARD_ADDR ] = LIVE_CLOBBERED_REG;
883
884       if (location->actualGPRLiveSet_[ REG_GUARD_OFFSET ] == LIVE_REG)
885     location->actualGPRLiveSet_[ REG_GUARD_OFFSET ] = LIVE_CLOBBERED_REG;
886
887       // GPR and FPR scratch registers, if live, must be saved
888       if (location->actualGPRLiveSet_[ REG_SCRATCH ] == LIVE_REG)
889     location->actualGPRLiveSet_[ REG_SCRATCH ] = LIVE_CLOBBERED_REG;
890
891       if (location->actualFPRLiveSet_[ REG_SCRATCH ] == LIVE_REG)
892     location->actualFPRLiveSet_[ REG_SCRATCH ] = LIVE_CLOBBERED_REG;
893
894       // Return func call register, since we make a call because
895       // of multithreading (regardless if it's threaded) from BT
896       // we must save return register
897       if (location->actualGPRLiveSet_[ 3 ] == LIVE_REG)
898     location->actualGPRLiveSet_[ 3 ] = LIVE_CLOBBERED_REG;
899
900
901       for (u_int i = 0; i < getRegisterCount(); i++)
902     {
903       regSlot = getRegSlot(i);
904
905       if (  location->actualGPRLiveSet_[ (int) registers[i].number ] == LIVE_REG )
906         {
907           if (!registers[i].beenClobbered)
908         location->actualGPRLiveSet_[ (int) registers[i].number ] = LIVE_UNCLOBBERED_REG;
909           else
910         location->actualGPRLiveSet_[ (int) registers[i].number ] = LIVE_CLOBBERED_REG;
911         }
912
913
914       if (  location->actualGPRLiveSet_[ (int) registers[i].number ] == LIVE_UNCLOBBERED_REG )
915         {
916           if (registers[i].beenClobbered)
917         location->actualGPRLiveSet_[ (int) registers[i].number ] = LIVE_CLOBBERED_REG;
918         }
919     }
920
921       for (u_int i = 0; i < getFPRegisterCount(); i++)
922     {
923       regFPSlot = getFPRegSlot(i);
924
925       if (  location->actualFPRLiveSet_[ (int) fpRegisters[i].number ] == LIVE_REG )
926         {
927           if (!fpRegisters[i].beenClobbered)
928         location->actualFPRLiveSet_[ (int) fpRegisters[i].number ] = LIVE_UNCLOBBERED_REG;
929           else
930         location->actualFPRLiveSet_[ (int) fpRegisters[i].number ] = LIVE_CLOBBERED_REG;
931         }
932
933       if (  location->actualFPRLiveSet_[ (int) fpRegisters[i].number ] == LIVE_UNCLOBBERED_REG )
934         {
935           if (fpRegisters[i].beenClobbered)
936         location->actualFPRLiveSet_[ (int) fpRegisters[i].number ] = LIVE_CLOBBERED_REG;
937         }
938     }
939     }
940 }
941 #endif
942
943
944 bool doNotOverflow(int value) {
945     // This function seems irrelevant for aarch64 two reasons:
946     // 1) it's used only once in Operator AST node and
947     // 2) when value is passed to emitImm, it ends in a moveValueToReg or it's 
948     //    checked before calling generateAddSubImmediate or moveValueToReg.
949     return true;
950
951     // (old code that seems to be copied from power implementation)
952     // we are assuming that we have 15 bits to store the immediate operand.
953     //if ((value <= 32767) && (value >= -32768)) return (true);
954     //else return (false);
955 }
956
957 #if !defined(os_vxworks)
958
959 // hasBeenBound: returns true if the runtime linker has bound the
960 // function symbol corresponding to the relocation entry in at the address
961 // specified by entry and base_addr.  If it has been bound, then the callee
962 // function is returned in "target_pdf", else it returns false.
963 bool PCProcess::hasBeenBound(const SymtabAPI::relocationEntry &entry,
964                              func_instance *&target_pdf, Address base_addr) {
965     assert(0); //Not implemented
966     return false;
967 }
968
969 #endif
970
971 bool PCProcess::bindPLTEntry(const SymtabAPI::relocationEntry &, Address,
972                              func_instance *, Address) {
973     assert(0); //Not implemented
974     assert(0 && "TODO!");
975     return false;
976 }
977
978 void emitLoadPreviousStackFrameRegister(Address register_num,
979                                         Register dest,
980                                         codeGen &gen,
981                                         int /*size*/,
982                                         bool noCost) {
983     assert(0); //Not implemented
984 }
985
986 void emitStorePreviousStackFrameRegister(Address,
987                                          Register,
988                                          codeGen &,
989                                          int,
990                                          bool) {
991     assert(0);
992 }
993
994 using namespace Dyninst::InstructionAPI;
995
996 bool AddressSpace::getDynamicCallSiteArgs(InstructionAPI::Instruction::Ptr i,
997                                           Address addr,
998                                           pdvector <AstNodePtr> &args) {
999     assert(0); //Not implemented
1000     return false;
1001 }
1002
1003 bool writeFunctionPtr(AddressSpace *p, Address addr, func_instance *f) {
1004     assert(0); //Not implemented
1005     return false;
1006 }
1007
1008 Emitter *AddressSpace::getEmitter() {
1009     static EmitterAARCH64Stat emitter64Stat;
1010     static EmitterAARCH64Dyn emitter64Dyn;
1011
1012     if (proc())
1013         return &emitter64Dyn;
1014
1015     return &emitter64Stat;
1016 }
1017
1018 #define GET_IP      0x429f0005
1019 #define MFLR_30     0x7fc802a6
1020 #define ADDIS_30_30 0x3fde0000
1021 #define ADDI_30_30  0x3bde0000
1022 #define LWZ_11_30   0x817e0000
1023 #define ADDIS_11_30 0x3d7e0000
1024
1025 /*
1026  * If the target stub_addr is a glink stub, try to determine the actual
1027  * function called (through the GOT) and fill in that information.
1028  *
1029  * The function at stub_addr may not have been created when this method
1030  * is called.
1031  *
1032  * XXX Is this a candidate to move into general parsing code, or is
1033  *     this properly a Dyninst-only technique?
1034  */
1035
1036 /*
1037 bool image::updatePltFunc(parse_func *caller_func, Address stub_addr)
1038 {
1039         assert(0); //Not implemented
1040     return true;
1041 }
1042 */
1043
1044 bool EmitterAARCH64::emitCallRelative(Register dest, Address offset, Register base, codeGen &gen) {
1045     assert(0); //Not implemented
1046     return true;
1047 }
1048
1049 bool EmitterAARCH64::emitLoadRelative(Register dest, Address offset, Register base, int size, codeGen &gen) {
1050     assert(0); //Not implemented
1051     return true;
1052 }
1053
1054
1055 void EmitterAARCH64::emitStoreRelative(Register source, Address offset, Register base, int size, codeGen &gen) {
1056     //return true;
1057     assert(0); //Not implemented
1058 }
1059
1060 bool EmitterAARCH64::emitMoveRegToReg(registerSlot *src,
1061                                       registerSlot *dest,
1062                                       codeGen &gen) {
1063     assert(0); //Not implemented
1064     return true;
1065 }
1066
1067 /*
1068 bool EmitterAARCH6432Stat::emitPIC(codeGen& gen, Address origAddr, Address relocAddr) {
1069
1070       Register scratchPCReg = gen.rs()->getScratchRegister(gen, true);
1071       pdvector<Register> excludeReg;
1072       excludeReg.push_back(scratchPCReg);
1073       Register scratchReg = gen.rs()->getScratchRegister(gen, excludeReg, true);
1074       bool newStackFrame = false;
1075       int stack_size = 0;
1076       int gpr_off, fpr_off, ctr_off;
1077       //fprintf(stderr, " emitPIC origAddr 0x%lx reloc 0x%lx Registers PC %d scratch %d \n", origAddr, relocAddr, scratchPCReg, scratchReg);
1078       if ((scratchPCReg == REG_NULL) || (scratchReg == REG_NULL)) {
1079                 //fprintf(stderr, " Creating new stack frame for 0x%lx to 0x%lx \n", origAddr, relocAddr);
1080
1081                 newStackFrame = true;
1082                 //create new stack frame
1083                 gpr_off = TRAMP_GPR_OFFSET_32;
1084                 fpr_off = TRAMP_FPR_OFFSET_32;
1085                 ctr_off = STK_CTR_32;
1086
1087                 // Make a stack frame.
1088                 pushStack(gen);
1089
1090                 // Save GPRs
1091               stack_size = saveGPRegisters(gen, gen.rs(), gpr_off, 2);
1092
1093               scratchPCReg = gen.rs()->getScratchRegister(gen, true);
1094               assert(scratchPCReg != REG_NULL);
1095               excludeReg.clear();
1096               excludeReg.push_back(scratchPCReg);
1097               scratchReg = gen.rs()->getScratchRegister(gen, excludeReg, true);
1098               assert(scratchReg != REG_NULL);
1099               // relocaAddr has moved since we added instructions to setup a new stack frame
1100               relocAddr = relocAddr + ((stack_size + 1)*(gen.width()));
1101               //fprintf(stderr, " emitPIC origAddr 0x%lx reloc 0x%lx stack size %d Registers PC %d scratch %d \n", origAddr, relocAddr, stack_size, scratchPCReg, scratchReg);
1102
1103         }
1104         emitMovePCToReg(scratchPCReg, gen);
1105         Address varOffset = origAddr - relocAddr;
1106         emitCallRelative(scratchReg, varOffset, scratchPCReg, gen);
1107         insnCodeGen::generateMoveToLR(gen, scratchReg);
1108         if(newStackFrame) {
1109               // GPRs
1110               restoreGPRegisters(gen, gen.rs(), gpr_off);
1111               popStack(gen);
1112         }
1113
1114       return 0;
1115 }
1116
1117 bool EmitterAARCH64Stat::emitPIC(codeGen& gen, Address origAddr, Address relocAddr) {
1118         assert(0);
1119         return false;
1120 }
1121 bool EmitterAARCH64Dyn::emitPIC(codeGen &gen, Address origAddr, Address relocAddr) {
1122
1123         Address origRet = origAddr + 4;
1124         Register scratch = gen.rs()->getScratchRegister(gen, true);
1125         assert(scratch != REG_NULL);
1126         instruction::loadImmIntoReg(gen, scratch, origRet);
1127         insnCodeGen::generateMoveToLR(gen, scratch);
1128         return true;
1129
1130 }
1131 */
1132
1133 bool EmitterAARCH64Stat::emitPLTCommon(func_instance *callee, bool call, codeGen &gen) {
1134     assert(0); //Not implemented
1135     return true;
1136 }
1137
1138 #if 0
1139 bool EmitterAARCH64Stat::emitPLTCommon(func_instance *callee, bool call, codeGen &gen) {
1140   // In PPC64 Linux, function descriptors are used in place of direct
1141   // function pointers.  The descriptors have the following layout:
1142   //
1143   // Function Descriptor --> + 0: <Function Text Address>
1144   //                         + 8: <TOC Pointer Value>
1145   //                         +16: <Environment Pointer [Optional]>
1146   //
1147   // Additionally, this should be able to stomp on the link register (LR)
1148   // and TOC register (r2), as they were saved by Emitter::emitCall() if
1149   // necessary.
1150   //
1151   // So here's a brief sketch of the code this function generates:
1152   //
1153   //   Set up new branch target in LR from function descriptor
1154   //   Set up new TOC in R2 from function descriptor + 8
1155   //   Call
1156   bool isStaticBinary = false;
1157
1158   if(gen.addrSpace()->edit()->getMappedObject()->parse_img()->getObject()->isStaticBinary()) {
1159     isStaticBinary = true;
1160   }
1161
1162   const unsigned TOCreg = 2;
1163   const unsigned wordsize = gen.width();
1164   assert(wordsize == 8);
1165   Address dest = getInterModuleFuncAddr(callee, gen);
1166   Address caller_toc = 0;
1167   Address toc_anchor = gen.addrSpace()->getTOCoffsetInfo(callee);
1168   // Instead of saving the TOC (if we can't), just reset it afterwards.
1169   if (gen.func()) {
1170     caller_toc = gen.addrSpace()->getTOCoffsetInfo(gen.func());
1171   }
1172   else if (gen.point()) {
1173     caller_toc = gen.addrSpace()->getTOCoffsetInfo(gen.point()->func());
1174   }
1175   else {
1176     // Don't need it, and this might be an iRPC
1177   }
1178
1179   if(isStaticBinary)
1180     caller_toc = 0;
1181
1182   //Offset destOff = dest - gen.currAddr();
1183   Offset destOff = dest - caller_toc;
1184
1185   //    insnCodeGen::loadPartialImmIntoReg(gen, TOCreg, destOff);
1186   // Broken to see if any of this generates intellible code.
1187
1188   Register scratchReg = 3; // = gen.rs()->getScratchRegister(gen, true);
1189   int stackSize = 0;
1190   if (scratchReg == REG_NULL) {
1191     pdvector<Register> freeReg;
1192     pdvector<Register> excludeReg;
1193     stackSize = insnCodeGen::createStackFrame(gen, 1, freeReg, excludeReg);
1194     assert (stackSize == 1);
1195     scratchReg = freeReg[0];
1196   }
1197   insnCodeGen::loadImmIntoReg<Offset?(gen, scratchReg, destOff);
1198
1199   if(!isStaticBinary) {
1200     insnCodeGen::generateLoadReg64(gen, scratchReg, scratchReg, TOCreg);
1201
1202     insnCodeGen::generateMemAccess64(gen, LDop, LDxop,
1203                      TOCreg, scratchReg, 8);
1204   }
1205   insnCodeGen::generateMemAccess64(gen, LDop, LDxop,
1206                    scratchReg, scratchReg, 0);
1207
1208   insnCodeGen::generateMoveToCR(gen, scratchReg);
1209
1210   if (stackSize > 0)
1211     insnCodeGen::removeStackFrame(gen);
1212
1213
1214   instruction branch_insn(call ? BCTRLraw : BCTRraw);
1215   insnCodeGen::generate(gen, branch_insn);
1216
1217   return true;
1218 }
1219 #endif
1220
1221 bool EmitterAARCH64Dyn::emitTOCCommon(block_instance *block, bool call, codeGen &gen) {
1222     assert(0); //Not implemented
1223     return true;
1224 }
1225
1226 // TODO 32/64-bit?
1227 bool EmitterAARCH64Stat::emitPLTCall(func_instance *callee, codeGen &gen) {
1228     assert(0); //Not implemented
1229     return emitPLTCommon(callee, true, gen);
1230 }
1231
1232 bool EmitterAARCH64Stat::emitPLTJump(func_instance *callee, codeGen &gen) {
1233     assert(0); //Not implemented
1234     return emitPLTCommon(callee, false, gen);
1235 }
1236
1237 bool EmitterAARCH64Stat::emitTOCCall(block_instance *block, codeGen &gen) {
1238     assert(0); //Not implemented
1239     return emitTOCCommon(block, true, gen);
1240 }
1241
1242 bool EmitterAARCH64Stat::emitTOCJump(block_instance *block, codeGen &gen) {
1243     assert(0); //Not implemented
1244     return emitTOCCommon(block, false, gen);
1245 }
1246
1247 bool EmitterAARCH64Stat::emitTOCCommon(block_instance *block, bool call, codeGen &gen) {
1248     assert(0); //Not implemented
1249     return false;
1250 }
1251
1252 bool EmitterAARCH64Stat::emitCallInstruction(codeGen &gen,
1253                                              func_instance *callee,
1254                                              bool setTOC, Address) {
1255     assert(0); //Not implemented
1256     return true;
1257 }
1258
1259 // Generates call instruction sequence for all AARCH64-based systems
1260 // under dynamic instrumentation.
1261 //
1262 // This should be able to stomp on the link register (LR) and TOC
1263 // register (r2), as they were saved by Emitter::emitCall() as necessary.
1264 bool EmitterAARCH64::emitCallInstruction(codeGen &gen, func_instance *callee, bool setTOC, Address toc_anchor) {
1265     assert(0); //Not implemented
1266     return true;
1267 }
1268
1269 void EmitterAARCH64::emitLoadShared(opCode op, Register dest, const image_variable *var, bool is_local, int size,
1270                                     codeGen &gen, Address offset) {
1271     assert(0); //Not implemented
1272     return;
1273 }
1274
1275 void
1276 EmitterAARCH64::emitStoreShared(Register source, const image_variable *var, bool is_local, int size, codeGen &gen) {
1277     assert(0); //Not implemented
1278     return;
1279 }
1280
1281 Address Emitter::getInterModuleVarAddr(const image_variable *var, codeGen &gen) {
1282     assert(0); //Not implemented
1283     AddressSpace *addrSpace = gen.addrSpace();
1284     if (!addrSpace)
1285         assert(0 && "No AddressSpace associated with codeGen object");
1286
1287     BinaryEdit *binEdit = addrSpace->edit();
1288     Address relocation_address;
1289     return relocation_address;
1290 }
1291
1292 Address EmitterAARCH64::emitMovePCToReg(Register dest, codeGen &gen) {
1293     assert(0); //Not implemented
1294     insnCodeGen::generateBranch(gen, gen.currAddr(), gen.currAddr() + 4, true); // blrl
1295     Address ret = gen.currAddr();
1296     return ret;
1297 }
1298
1299 Address Emitter::getInterModuleFuncAddr(func_instance *func, codeGen &gen) {
1300     assert(0); //Not implemented
1301     return NULL;
1302 }
1303
1304
1305
1306