Merge branch 'master' into new-parallel-parsing
[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                 if(src2imm >= -(1 << 11) && src2imm < (long int)((1 << 11) - 1))
461                     insnCodeGen::generateAddSubImmediate(gen,
462                             op == plusOp ? insnCodeGen::Add : insnCodeGen::Sub, 0,
463                             src2imm, src1, dest, false);
464                 else if(src2imm >= MIN_IMM16 && src2imm < MAX_IMM16)
465                 {
466                     Register rm = insnCodeGen::moveValueToReg(gen, src2imm);
467                     insnCodeGen::generateAddSubShifted(gen,
468                             op == plusOp ? insnCodeGen::Add : insnCodeGen::Sub,
469                             0, 0, rm, src1, dest, true);
470                 }
471             }
472             break;
473         case timesOp:
474             {
475                 Register rm = insnCodeGen::moveValueToReg(gen, src2imm);
476                 insnCodeGen::generateMul(gen, rm, src1, dest, true);
477             }
478             break;
479         case divOp:
480             {
481                 Register rm = insnCodeGen::moveValueToReg(gen, src2imm);
482                 insnCodeGen::generateDiv(gen, rm, src1, dest, true);
483             }
484             break;
485         case xorOp:
486             {
487                 Register rm = insnCodeGen::moveValueToReg(gen, src2imm);
488                 insnCodeGen::generateBitwiseOpShifted(gen, insnCodeGen::Eor, 0, rm, 0, src1, dest, true);
489             }
490             break;
491         case orOp:
492             {
493                 Register rm = insnCodeGen::moveValueToReg(gen, src2imm);
494                 insnCodeGen::generateBitwiseOpShifted(gen, insnCodeGen::Or, 0, rm, 0, src1, dest, true);
495             }
496             break;
497         case andOp:
498             {
499                 Register rm = insnCodeGen::moveValueToReg(gen, src2imm);
500                 insnCodeGen::generateBitwiseOpShifted(gen, insnCodeGen::And, 0, rm, 0, src1, dest, true);
501             }
502             break;
503         case eqOp:
504             {
505                 Register scratch = gen.rs()->getScratchRegister(gen);
506                 emitVload(loadConstOp, src2imm, NULL, scratch, gen, true);
507                 emitV(op, src1, scratch, dest, gen, true);
508             }
509             break;
510         case neOp:
511         case lessOp:
512         case leOp:
513         case greaterOp:
514         case geOp:
515             // note that eqOp could be grouped here too.
516             // There's two ways to implement this.
517             gen.codeEmitter()->emitRelOpImm(op, dest, src1, src2imm, gen);
518             return;
519         default:
520             assert(0); // not implemented or not valid
521             break;
522     }
523 }
524
525 void cleanUpAndExit(int status);
526
527 /* Recursive function that goes to where our instrumentation is calling
528 to figure out what registers are clobbered there, and in any function
529 that it calls, to a certain depth ... at which point we clobber everything
530
531 Update-12/06, njr, since we're going to a cached system we are just going to
532 look at the first level and not do recursive, since we would have to also
533 store and reexamine every call out instead of doing it on the fly like before*/
534 bool EmitterAARCH64::clobberAllFuncCall(registerSpace *rs,
535                                         func_instance *callee) {
536     if(!callee)
537         return true;
538
539     stats_codegen.startTimer(CODEGEN_LIVENESS_TIMER);
540
541     if(callee->ifunc()->isLeafFunc()) {
542         std::set<Register> *gpRegs = callee->ifunc()->usedGPRs();
543         for(std::set<Register>::iterator itr = gpRegs->begin(); itr != gpRegs->end(); itr++)
544             rs->GPRs()[*itr]->beenUsed = true;
545
546         std::set<Register> *fpRegs = callee->ifunc()->usedFPRs();
547         for(std::set<Register>::iterator itr = fpRegs->begin(); itr != fpRegs->end(); itr++)
548             rs->FPRs()[*itr]->beenUsed = true;
549     } else {
550         for(int idx = 0; idx < rs->numGPRs(); idx++)
551             rs->GPRs()[idx]->beenUsed = true;
552         for(int idx = 0; idx < rs->numFPRs(); idx++)
553             rs->FPRs()[idx]->beenUsed = true;
554     }
555
556     stats_codegen.stopTimer(CODEGEN_LIVENESS_TIMER);
557
558     return false;
559 }
560
561 Register emitFuncCall(opCode, codeGen &, std::vector <AstNodePtr> &, bool, Address) {
562     assert(0);
563     return 0;
564 }
565
566 Register emitFuncCall(opCode op,
567                       codeGen &gen,
568                       std::vector <AstNodePtr> &operands, bool noCost,
569                       func_instance *callee) {
570     return gen.emitter()->emitCall(op, gen, operands, noCost, callee);
571 }
572
573 Register EmitterAARCH64::emitCallReplacement(opCode ocode,
574                                              codeGen &gen,
575                                              bool /* noCost */,
576                                              func_instance *callee) {
577     assert(0); //Not implemented
578     return 0;
579 }
580
581 // There are four "axes" going on here:
582 // 32 bit vs 64 bit
583 // Instrumentation vs function call replacement
584 // Static vs. dynamic
585
586 Register EmitterAARCH64::emitCall(opCode op,
587                                   codeGen &gen,
588                                   const std::vector<AstNodePtr> &operands,
589                                   bool noCost,
590                                   func_instance *callee) 
591 {
592     //#sasha This function implementation is experimental.
593
594     if (op != callOp) {
595         cerr << "ERROR: emitCall with op == " << op << endl;
596     }
597     assert(op == callOp);
598
599     std::vector<Register> srcs;
600     std::vector<Register> saves;
601
602     //  Sanity check for NULL address arg
603     if (!callee) 
604     {
605         char msg[256];
606         sprintf(msg, "%s[%d]:  internal error:  emitFuncCall called w/out"
607                 "callee argument", __FILE__, __LINE__);
608         showErrorCallback(80, msg);
609         assert(0);
610     }
611
612     vector<int> savedRegs;
613
614     // save r0-r7
615     for(size_t id = 0; id < gen.rs()->numGPRs(); id++)
616     {
617         registerSlot *reg = gen.rs()->GPRs()[id];
618
619         // We must save if:
620         // refCount > 0 (and not a source register)
621         // keptValue == true (keep over the call)
622         // liveState == live (technically, only if not saved by the callee)
623
624         if ((reg->refCount > 0) || reg->keptValue || (reg->liveState == registerSlot::live))
625         {
626             insnCodeGen::saveRegister(gen, registerSpace::r0 + id,
627                     -2*GPRSIZE_64, insnCodeGen::Post);
628             savedRegs.push_back(reg->number);
629         }
630     }
631
632     // Passing operands to registers
633     for(size_t id = 0; id < operands.size(); id++)
634     {
635         Register reg = REG_NULL;
636         if (gen.rs()->allocateSpecificRegister(gen, registerSpace::r0 + id, true))
637             reg = registerSpace::r0 + id;
638
639         Address unnecessary = ADDR_NULL;
640         if (!operands[id]->generateCode_phase2(gen, false, unnecessary, reg))
641             assert(0);
642         assert(reg!=REG_NULL);
643     }
644
645     //instPoint *point = gen.point();
646     //assert(point);
647     assert(gen.rs());
648
649     //Address of function to call in scratch register
650     Register scratch = gen.rs()->getScratchRegister(gen);
651     assert(scratch!=REG_NULL);
652     gen.markRegDefined(scratch);
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                 2*GPRSIZE_64, insnCodeGen::Post);
679     }
680
681     return 0;
682 }
683
684
685 codeBufIndex_t emitA(opCode op, Register src1, Register src2, long dest,
686         codeGen &gen, RegControl rc, bool noCost)
687 {
688     codeBufIndex_t retval = 0;
689
690     switch (op) {
691         case ifOp: 
692             {
693                 // if src1 == 0 jump to dest
694                 // src1 is a temporary
695                 // dest is a target address
696                 retval = gen.codeEmitter()->emitIf(src1, dest, rc, gen);
697                 break;
698             }
699         default:
700             assert(0);        // op not implemented or not expected for this emit!
701     }
702
703     return retval;
704 }
705
706 Register emitR(opCode op, Register src1, Register src2, Register dest,
707                codeGen &gen, bool /*noCost*/,
708                const instPoint * location, bool /*for_MT*/)
709 {
710     registerSlot *regSlot = NULL;
711     unsigned addrWidth = gen.width();
712
713     switch(op){
714         case getRetValOp:
715             regSlot = (*(gen.rs()))[registerSpace::r0];
716             break;
717         case getParamOp:
718             // src1 is the number of the argument
719             // dest is a register where we can store the value
720             //gen.codeEmitter()->emitGetParam(dest, src1, location->type(), op,
721             //        false, gen);
722
723             if(src1 <= 7) {
724                 // src1 is 0..7 - it's a parameter order number, not a register
725                 regSlot = (*(gen.rs()))[registerSpace::r0 + src1];
726                 break;
727
728             } else {
729                 assert(0);
730             }
731             break;
732         default:
733             assert(0);
734     }
735
736     assert(regSlot);
737     Register reg = regSlot->number;
738
739     switch(regSlot->liveState) {
740         case registerSlot::spilled:
741             {
742                 int offset = TRAMP_GPR_OFFSET(addrWidth);
743                 // its on the stack so load it.
744                 //if (src2 != REG_NULL) saveRegister(gen, src2, reg, offset);
745                 insnCodeGen::restoreRegister(gen, dest, offset + (reg * gen.width()));
746                 return(dest);
747             }
748         case registerSlot::live:
749             {
750                 // its still in a register so return the register it is in.
751                 cerr << "emitR state:" << reg << " live" << endl;
752                 assert(0);
753                 return(reg);
754             }
755         case registerSlot::dead:
756             {
757                 cerr << "emitR state" << reg << ": dead" << endl;
758                 // Uhhh... wha?
759                 assert(0);
760             }
761     }
762     return reg;
763 }
764
765 void emitJmpMC(int /*condition*/, int /*offset*/, codeGen &) {
766     assert(0); //Not implemented
767     // Not needed for memory instrumentation, otherwise TBD
768 }
769
770
771 // VG(11/16/01): Say if we have to restore a register to get its original value
772 // VG(03/15/02): Sync'd with the new AIX tramp
773 static inline bool needsRestore(Register x) {
774     assert(0); //Not implemented
775     return false;
776 }
777
778 // VG(03/15/02): Restore mutatee value of GPR reg to dest GPR
779 static inline void restoreGPRtoGPR(codeGen &gen,
780                                    Register reg, Register dest) {
781     assert(0); //Not implemented
782 }
783
784 // VG(03/15/02): Restore mutatee value of XER to dest GPR
785 static inline void restoreXERtoGPR(codeGen &gen, Register dest) {
786     assert(0); //Not implemented
787 }
788
789 // VG(03/15/02): Move bits 25:31 of GPR reg to GPR dest
790 static inline void moveGPR2531toGPR(codeGen &gen,
791                                     Register reg, Register dest) {
792     assert(0); //Not implemented
793 }
794
795 // VG(11/16/01): Emit code to add the original value of a register to
796 // another. The original value may need to be restored from stack...
797 // VG(03/15/02): Made functionality more obvious by adding the above functions
798 static inline void emitAddOriginal(Register src, Register acc,
799                                    codeGen &gen, bool noCost) {
800     assert(0); //Not implemented
801 }
802
803 // VG(11/07/01): Load in destination the effective address given
804 // by the address descriptor. Used for memory access stuff.
805 void emitASload(const BPatch_addrSpec_NP *as, Register dest, int stackShift,
806                 codeGen &gen,
807                 bool noCost) {
808     assert(0); //Not implemented
809 }
810
811 void emitCSload(const BPatch_addrSpec_NP *as, Register dest, codeGen &gen,
812                 bool noCost) {
813     assert(0); //Not implemented
814 }
815
816 void emitVload(opCode op, Address src1, Register src2, Register dest,
817                codeGen &gen, bool /*noCost*/,
818                registerSpace * /*rs*/, int size,
819                const instPoint * /* location */, AddressSpace *proc)
820 {
821     switch(op)
822     {
823         case loadConstOp:
824             // dest is a temporary
825             // src1 is an immediate value
826             // dest = src1:imm32
827             gen.codeEmitter()->emitLoadConst(dest, src1, gen);
828             break;
829         case loadOp:
830             // dest is a temporary
831             // src1 is the address of the operand
832             // dest = [src1]
833             gen.codeEmitter()->emitLoad(dest, src1, size, gen);
834             break;
835         default:
836             assert(0); //Not implemented
837             break;
838     }
839 }
840
841 void emitVstore(opCode op, Register src1, Register /*src2*/, Address dest,
842                 codeGen &gen, bool noCost,
843                 registerSpace * /* rs */, int size,
844                 const instPoint * /* location */, AddressSpace *proc)
845 {
846     if (op ==  storeOp) {
847         // [dest] = src1
848         // dest has the address where src1 is to be stored
849         // src1 is a temporary
850         // src2 is a "scratch" register, we don't need it in this architecture
851         gen.codeEmitter()->emitStore(dest, src1, size, gen);
852     }else{
853         assert(0); //Not implemented
854     }
855     return;
856 }
857
858 void emitV(opCode op, Register src1, Register src2, Register dest,
859            codeGen &gen, bool /*noCost*/,
860            registerSpace * /*rs*/, int size,
861            const instPoint * /* location */, AddressSpace *proc) 
862 {
863     switch(op){
864         case plusOp:
865         case minusOp:
866         case divOp:
867         case timesOp:
868         case orOp:
869         case andOp:
870         case xorOp:
871             gen.codeEmitter()->emitOp(op, dest, src1, src2, gen);
872             break;
873         case lessOp:
874         case leOp:
875         case greaterOp:
876         case geOp:
877         case eqOp:
878         case neOp:
879             gen.codeEmitter()->emitRelOp(op, dest, src1, src2, gen);
880             break;
881         default:
882             //std::cout << "operation= " << op << endl;
883             assert(0); // Not implemented
884             break;
885     }
886     return;
887 }
888
889 //
890 // I don't know how to compute cycles for AARCH64 instructions due to
891 //   multiple functional units.  However, we can compute the number of
892 //   instructions and hope that is fairly close. - jkh 1/30/96
893 //
894 int getInsnCost(opCode op) {
895     assert(0); //Not implemented
896     return NULL;
897 }
898
899 #if 0
900 // What does this do???
901 void registerSpace::saveClobberInfo(const instPoint *location)
902 {
903   registerSlot *regSlot = NULL;
904   registerSlot *regFPSlot = NULL;
905   if (location == NULL)
906     return;
907   if (location->actualGPRLiveSet_ != NULL && location->actualFPRLiveSet_ != NULL)
908     {
909
910       // REG guard registers, if live, must be saved
911       if (location->actualGPRLiveSet_[ REG_GUARD_ADDR ] == LIVE_REG)
912     location->actualGPRLiveSet_[ REG_GUARD_ADDR ] = LIVE_CLOBBERED_REG;
913
914       if (location->actualGPRLiveSet_[ REG_GUARD_OFFSET ] == LIVE_REG)
915     location->actualGPRLiveSet_[ REG_GUARD_OFFSET ] = LIVE_CLOBBERED_REG;
916
917       // GPR and FPR scratch registers, if live, must be saved
918       if (location->actualGPRLiveSet_[ REG_SCRATCH ] == LIVE_REG)
919     location->actualGPRLiveSet_[ REG_SCRATCH ] = LIVE_CLOBBERED_REG;
920
921       if (location->actualFPRLiveSet_[ REG_SCRATCH ] == LIVE_REG)
922     location->actualFPRLiveSet_[ REG_SCRATCH ] = LIVE_CLOBBERED_REG;
923
924       // Return func call register, since we make a call because
925       // of multithreading (regardless if it's threaded) from BT
926       // we must save return register
927       if (location->actualGPRLiveSet_[ 3 ] == LIVE_REG)
928     location->actualGPRLiveSet_[ 3 ] = LIVE_CLOBBERED_REG;
929
930
931       for (u_int i = 0; i < getRegisterCount(); i++)
932     {
933       regSlot = getRegSlot(i);
934
935       if (  location->actualGPRLiveSet_[ (int) registers[i].number ] == LIVE_REG )
936         {
937           if (!registers[i].beenClobbered)
938         location->actualGPRLiveSet_[ (int) registers[i].number ] = LIVE_UNCLOBBERED_REG;
939           else
940         location->actualGPRLiveSet_[ (int) registers[i].number ] = LIVE_CLOBBERED_REG;
941         }
942
943
944       if (  location->actualGPRLiveSet_[ (int) registers[i].number ] == LIVE_UNCLOBBERED_REG )
945         {
946           if (registers[i].beenClobbered)
947         location->actualGPRLiveSet_[ (int) registers[i].number ] = LIVE_CLOBBERED_REG;
948         }
949     }
950
951       for (u_int i = 0; i < getFPRegisterCount(); i++)
952     {
953       regFPSlot = getFPRegSlot(i);
954
955       if (  location->actualFPRLiveSet_[ (int) fpRegisters[i].number ] == LIVE_REG )
956         {
957           if (!fpRegisters[i].beenClobbered)
958         location->actualFPRLiveSet_[ (int) fpRegisters[i].number ] = LIVE_UNCLOBBERED_REG;
959           else
960         location->actualFPRLiveSet_[ (int) fpRegisters[i].number ] = LIVE_CLOBBERED_REG;
961         }
962
963       if (  location->actualFPRLiveSet_[ (int) fpRegisters[i].number ] == LIVE_UNCLOBBERED_REG )
964         {
965           if (fpRegisters[i].beenClobbered)
966         location->actualFPRLiveSet_[ (int) fpRegisters[i].number ] = LIVE_CLOBBERED_REG;
967         }
968     }
969     }
970 }
971 #endif
972
973
974 bool doNotOverflow(int value) {
975     // This function seems irrelevant for aarch64 two reasons:
976     // 1) it's used only once in Operator AST node and
977     // 2) when value is passed to emitImm, it ends in a moveValueToReg or it's 
978     //    checked before calling generateAddSubImmediate or moveValueToReg.
979     return true;
980
981     // (old code that seems to be copied from power implementation)
982     // we are assuming that we have 15 bits to store the immediate operand.
983     //if ((value <= 32767) && (value >= -32768)) return (true);
984     //else return (false);
985 }
986
987 #if !defined(os_vxworks)
988
989 // hasBeenBound: returns true if the runtime linker has bound the
990 // function symbol corresponding to the relocation entry in at the address
991 // specified by entry and base_addr.  If it has been bound, then the callee
992 // function is returned in "target_pdf", else it returns false.
993 bool PCProcess::hasBeenBound(const SymtabAPI::relocationEntry &entry,
994                              func_instance *&target_pdf, Address base_addr) {
995     assert(0); //Not implemented
996     return false;
997 }
998
999 #endif
1000
1001 bool PCProcess::bindPLTEntry(const SymtabAPI::relocationEntry &, Address,
1002                              func_instance *, Address) {
1003     assert(0); //Not implemented
1004     assert(0 && "TODO!");
1005     return false;
1006 }
1007
1008 void emitLoadPreviousStackFrameRegister(Address register_num,
1009                                         Register dest,
1010                                         codeGen &gen,
1011                                         int /*size*/,
1012                                         bool noCost) {
1013     assert(0); //Not implemented
1014 }
1015
1016 void emitStorePreviousStackFrameRegister(Address,
1017                                          Register,
1018                                          codeGen &,
1019                                          int,
1020                                          bool) {
1021     assert(0);
1022 }
1023
1024 using namespace Dyninst::InstructionAPI;
1025 bool AddressSpace::getDynamicCallSiteArgs(InstructionAPI::Instruction i,
1026                                           Address addr,
1027                                           pdvector<AstNodePtr> &args)
1028 {
1029         assert(0); //Not implemented
1030         return false;
1031 }
1032
1033 bool writeFunctionPtr(AddressSpace *p, Address addr, func_instance *f) {
1034     assert(0); //Not implemented
1035     return false;
1036 }
1037
1038 Emitter *AddressSpace::getEmitter() {
1039     static EmitterAARCH64Stat emitter64Stat;
1040     static EmitterAARCH64Dyn emitter64Dyn;
1041
1042     if (proc())
1043         return &emitter64Dyn;
1044
1045     return &emitter64Stat;
1046 }
1047
1048 #define GET_IP      0x429f0005
1049 #define MFLR_30     0x7fc802a6
1050 #define ADDIS_30_30 0x3fde0000
1051 #define ADDI_30_30  0x3bde0000
1052 #define LWZ_11_30   0x817e0000
1053 #define ADDIS_11_30 0x3d7e0000
1054
1055 /*
1056  * If the target stub_addr is a glink stub, try to determine the actual
1057  * function called (through the GOT) and fill in that information.
1058  *
1059  * The function at stub_addr may not have been created when this method
1060  * is called.
1061  *
1062  * XXX Is this a candidate to move into general parsing code, or is
1063  *     this properly a Dyninst-only technique?
1064  */
1065
1066 /*
1067 bool image::updatePltFunc(parse_func *caller_func, Address stub_addr)
1068 {
1069         assert(0); //Not implemented
1070     return true;
1071 }
1072 */
1073
1074 bool EmitterAARCH64::emitCallRelative(Register dest, Address offset, Register base, codeGen &gen) {
1075     assert(0); //Not implemented
1076     return true;
1077 }
1078
1079 bool EmitterAARCH64::emitLoadRelative(Register dest, Address offset, Register base, int size, codeGen &gen) {
1080     assert(0); //Not implemented
1081     return true;
1082 }
1083
1084
1085 void EmitterAARCH64::emitStoreRelative(Register source, Address offset, Register base, int size, codeGen &gen) {
1086     //return true;
1087     assert(0); //Not implemented
1088 }
1089
1090 bool EmitterAARCH64::emitMoveRegToReg(registerSlot *src,
1091                                       registerSlot *dest,
1092                                       codeGen &gen) {
1093     assert(0); //Not implemented
1094     return true;
1095 }
1096
1097 /*
1098 bool EmitterAARCH6432Stat::emitPIC(codeGen& gen, Address origAddr, Address relocAddr) {
1099
1100       Register scratchPCReg = gen.rs()->getScratchRegister(gen, true);
1101       std::vector<Register> excludeReg;
1102       excludeReg.push_back(scratchPCReg);
1103       Register scratchReg = gen.rs()->getScratchRegister(gen, excludeReg, true);
1104       bool newStackFrame = false;
1105       int stack_size = 0;
1106       int gpr_off, fpr_off, ctr_off;
1107       //fprintf(stderr, " emitPIC origAddr 0x%lx reloc 0x%lx Registers PC %d scratch %d \n", origAddr, relocAddr, scratchPCReg, scratchReg);
1108       if ((scratchPCReg == REG_NULL) || (scratchReg == REG_NULL)) {
1109                 //fprintf(stderr, " Creating new stack frame for 0x%lx to 0x%lx \n", origAddr, relocAddr);
1110
1111                 newStackFrame = true;
1112                 //create new stack frame
1113                 gpr_off = TRAMP_GPR_OFFSET_32;
1114                 fpr_off = TRAMP_FPR_OFFSET_32;
1115                 ctr_off = STK_CTR_32;
1116
1117                 // Make a stack frame.
1118                 pushStack(gen);
1119
1120                 // Save GPRs
1121               stack_size = saveGPRegisters(gen, gen.rs(), gpr_off, 2);
1122
1123               scratchPCReg = gen.rs()->getScratchRegister(gen, true);
1124               assert(scratchPCReg != REG_NULL);
1125               excludeReg.clear();
1126               excludeReg.push_back(scratchPCReg);
1127               scratchReg = gen.rs()->getScratchRegister(gen, excludeReg, true);
1128               assert(scratchReg != REG_NULL);
1129               // relocaAddr has moved since we added instructions to setup a new stack frame
1130               relocAddr = relocAddr + ((stack_size + 1)*(gen.width()));
1131               //fprintf(stderr, " emitPIC origAddr 0x%lx reloc 0x%lx stack size %d Registers PC %d scratch %d \n", origAddr, relocAddr, stack_size, scratchPCReg, scratchReg);
1132
1133         }
1134         emitMovePCToReg(scratchPCReg, gen);
1135         Address varOffset = origAddr - relocAddr;
1136         emitCallRelative(scratchReg, varOffset, scratchPCReg, gen);
1137         insnCodeGen::generateMoveToLR(gen, scratchReg);
1138         if(newStackFrame) {
1139               // GPRs
1140               restoreGPRegisters(gen, gen.rs(), gpr_off);
1141               popStack(gen);
1142         }
1143
1144       return 0;
1145 }
1146
1147 bool EmitterAARCH64Stat::emitPIC(codeGen& gen, Address origAddr, Address relocAddr) {
1148         assert(0);
1149         return false;
1150 }
1151 bool EmitterAARCH64Dyn::emitPIC(codeGen &gen, Address origAddr, Address relocAddr) {
1152
1153         Address origRet = origAddr + 4;
1154         Register scratch = gen.rs()->getScratchRegister(gen, true);
1155         assert(scratch != REG_NULL);
1156         instruction::loadImmIntoReg(gen, scratch, origRet);
1157         insnCodeGen::generateMoveToLR(gen, scratch);
1158         return true;
1159
1160 }
1161 */
1162
1163 bool EmitterAARCH64Stat::emitPLTCommon(func_instance *callee, bool call, codeGen &gen) {
1164     assert(0); //Not implemented
1165     return true;
1166 }
1167
1168 #if 0
1169 bool EmitterAARCH64Stat::emitPLTCommon(func_instance *callee, bool call, codeGen &gen) {
1170   // In PPC64 Linux, function descriptors are used in place of direct
1171   // function pointers.  The descriptors have the following layout:
1172   //
1173   // Function Descriptor --> + 0: <Function Text Address>
1174   //                         + 8: <TOC Pointer Value>
1175   //                         +16: <Environment Pointer [Optional]>
1176   //
1177   // Additionally, this should be able to stomp on the link register (LR)
1178   // and TOC register (r2), as they were saved by Emitter::emitCall() if
1179   // necessary.
1180   //
1181   // So here's a brief sketch of the code this function generates:
1182   //
1183   //   Set up new branch target in LR from function descriptor
1184   //   Set up new TOC in R2 from function descriptor + 8
1185   //   Call
1186   bool isStaticBinary = false;
1187
1188   if(gen.addrSpace()->edit()->getMappedObject()->parse_img()->getObject()->isStaticBinary()) {
1189     isStaticBinary = true;
1190   }
1191
1192   const unsigned TOCreg = 2;
1193   const unsigned wordsize = gen.width();
1194   assert(wordsize == 8);
1195   Address dest = getInterModuleFuncAddr(callee, gen);
1196   Address caller_toc = 0;
1197   Address toc_anchor = gen.addrSpace()->getTOCoffsetInfo(callee);
1198   // Instead of saving the TOC (if we can't), just reset it afterwards.
1199   if (gen.func()) {
1200     caller_toc = gen.addrSpace()->getTOCoffsetInfo(gen.func());
1201   }
1202   else if (gen.point()) {
1203     caller_toc = gen.addrSpace()->getTOCoffsetInfo(gen.point()->func());
1204   }
1205   else {
1206     // Don't need it, and this might be an iRPC
1207   }
1208
1209   if(isStaticBinary)
1210     caller_toc = 0;
1211
1212   //Offset destOff = dest - gen.currAddr();
1213   Offset destOff = dest - caller_toc;
1214
1215   //    insnCodeGen::loadPartialImmIntoReg(gen, TOCreg, destOff);
1216   // Broken to see if any of this generates intellible code.
1217
1218   Register scratchReg = 3; // = gen.rs()->getScratchRegister(gen, true);
1219   int stackSize = 0;
1220   if (scratchReg == REG_NULL) {
1221     std::vector<Register> freeReg;
1222     std::vector<Register> excludeReg;
1223     stackSize = insnCodeGen::createStackFrame(gen, 1, freeReg, excludeReg);
1224     assert (stackSize == 1);
1225     scratchReg = freeReg[0];
1226   }
1227   insnCodeGen::loadImmIntoReg<Offset?(gen, scratchReg, destOff);
1228
1229   if(!isStaticBinary) {
1230     insnCodeGen::generateLoadReg64(gen, scratchReg, scratchReg, TOCreg);
1231
1232     insnCodeGen::generateMemAccess64(gen, LDop, LDxop,
1233                      TOCreg, scratchReg, 8);
1234   }
1235   insnCodeGen::generateMemAccess64(gen, LDop, LDxop,
1236                    scratchReg, scratchReg, 0);
1237
1238   insnCodeGen::generateMoveToCR(gen, scratchReg);
1239
1240   if (stackSize > 0)
1241     insnCodeGen::removeStackFrame(gen);
1242
1243
1244   instruction branch_insn(call ? BCTRLraw : BCTRraw);
1245   insnCodeGen::generate(gen, branch_insn);
1246
1247   return true;
1248 }
1249 #endif
1250
1251 bool EmitterAARCH64Dyn::emitTOCCommon(block_instance *block, bool call, codeGen &gen) {
1252     assert(0); //Not implemented
1253     return true;
1254 }
1255
1256 // TODO 32/64-bit?
1257 bool EmitterAARCH64Stat::emitPLTCall(func_instance *callee, codeGen &gen) {
1258     assert(0); //Not implemented
1259     return emitPLTCommon(callee, true, gen);
1260 }
1261
1262 bool EmitterAARCH64Stat::emitPLTJump(func_instance *callee, codeGen &gen) {
1263     assert(0); //Not implemented
1264     return emitPLTCommon(callee, false, gen);
1265 }
1266
1267 bool EmitterAARCH64Stat::emitTOCCall(block_instance *block, codeGen &gen) {
1268     assert(0); //Not implemented
1269     return emitTOCCommon(block, true, gen);
1270 }
1271
1272 bool EmitterAARCH64Stat::emitTOCJump(block_instance *block, codeGen &gen) {
1273     assert(0); //Not implemented
1274     return emitTOCCommon(block, false, gen);
1275 }
1276
1277 bool EmitterAARCH64Stat::emitTOCCommon(block_instance *block, bool call, codeGen &gen) {
1278     assert(0); //Not implemented
1279     return false;
1280 }
1281
1282 bool EmitterAARCH64Stat::emitCallInstruction(codeGen &gen,
1283                                              func_instance *callee,
1284                                              bool setTOC, Address) {
1285     assert(0); //Not implemented
1286     return true;
1287 }
1288
1289 // Generates call instruction sequence for all AARCH64-based systems
1290 // under dynamic instrumentation.
1291 //
1292 // This should be able to stomp on the link register (LR) and TOC
1293 // register (r2), as they were saved by Emitter::emitCall() as necessary.
1294 bool EmitterAARCH64::emitCallInstruction(codeGen &gen, func_instance *callee, bool setTOC, Address toc_anchor) {
1295     assert(0); //Not implemented
1296     return true;
1297 }
1298
1299 void EmitterAARCH64::emitLoadShared(opCode op, Register dest, const image_variable *var, bool is_local, int size,
1300                                     codeGen &gen, Address offset) {
1301     assert(0); //Not implemented
1302     return;
1303 }
1304
1305 void
1306 EmitterAARCH64::emitStoreShared(Register source, const image_variable *var, bool is_local, int size, codeGen &gen) {
1307     assert(0); //Not implemented
1308     return;
1309 }
1310
1311 Address Emitter::getInterModuleVarAddr(const image_variable *var, codeGen &gen) {
1312     assert(0); //Not implemented
1313     AddressSpace *addrSpace = gen.addrSpace();
1314     if (!addrSpace)
1315         assert(0 && "No AddressSpace associated with codeGen object");
1316
1317     BinaryEdit *binEdit = addrSpace->edit();
1318     Address relocation_address;
1319     return relocation_address;
1320 }
1321
1322 Address EmitterAARCH64::emitMovePCToReg(Register dest, codeGen &gen) {
1323     assert(0); //Not implemented
1324     insnCodeGen::generateBranch(gen, gen.currAddr(), gen.currAddr() + 4, true); // blrl
1325     Address ret = gen.currAddr();
1326     return ret;
1327 }
1328
1329 Address Emitter::getInterModuleFuncAddr(func_instance *func, codeGen &gen) {
1330     assert(0); //Not implemented
1331     return NULL;
1332 }
1333
1334
1335
1336