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