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