Implements getDynamicCallSiteArgs to monitor dynamic call sites.
[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
187         if (reg->liveState == registerSlot::live) {
188             int offset_from_sp = offset + (reg->encoding() * gen.width());
189             insnCodeGen::saveRegister(gen, reg->number, offset_from_sp);
190             theRegSpace->markSavedRegister(reg->number, offset_from_sp);
191             ret++;
192         }
193     }
194
195     return ret;
196 }
197
198 unsigned EmitterAARCH64SaveRegs::saveFPRegisters(
199         codeGen &gen, registerSpace *theRegSpace, int offset)
200 {
201     unsigned ret = 0;
202
203     for(int idx = 0; idx < theRegSpace->numFPRs(); idx++) {
204         registerSlot *reg = theRegSpace->FPRs()[idx];
205
206         //if(reg->liveState == registerSlot::live) {
207             int offset_from_sp = offset + (reg->encoding() * FPRSIZE_64);
208             saveFPRegister(gen, reg->number, offset_from_sp);
209             //reg->liveState = registerSlot::spilled;
210             theRegSpace->markSavedRegister(reg->number, offset_from_sp);
211             ret++;
212         //}
213     }
214
215     return ret;
216 }
217
218 unsigned EmitterAARCH64SaveRegs::saveSPRegisters(
219         codeGen &gen, registerSpace *theRegSpace, int offset, bool force_save)
220 {
221     int ret = 0;
222
223     std::vector<registerSlot *> spRegs;
224     map<registerSlot *, int> regMap;
225
226     registerSlot *regNzcv = (*theRegSpace)[registerSpace::pstate];
227     assert(regNzcv);
228     regMap[regNzcv] = SPR_NZCV;
229     if(force_save || regNzcv->liveState == registerSlot::live)
230         spRegs.push_back(regNzcv);
231
232     registerSlot *regFpcr = (*theRegSpace)[registerSpace::fpcr];
233     assert(regFpcr);
234     regMap[regFpcr] = SPR_FPCR;
235     if(force_save || regFpcr->liveState == registerSlot::live)
236         spRegs.push_back(regFpcr);
237
238     registerSlot *regFpsr = (*theRegSpace)[registerSpace::fpsr];
239     assert(regFpsr);
240     regMap[regFpsr] = SPR_FPSR;
241     if(force_save || regFpsr->liveState == registerSlot::live)
242         spRegs.push_back(regFpsr);
243
244     for(std::vector<registerSlot *>::iterator itr = spRegs.begin(); itr != spRegs.end(); itr++) {
245         registerSlot *cur = *itr;
246         saveSPR(gen, theRegSpace->getScratchRegister(gen, true), regMap[cur], -4*GPRSIZE_32);
247         theRegSpace->markSavedRegister(cur->number, offset);
248
249         offset += 4*GPRSIZE_32;
250         ret++;
251     }
252
253     return ret;
254 }
255
256 void EmitterAARCH64SaveRegs::createFrame(codeGen &gen) {
257     //Save link register
258     Register linkRegister = gen.rs()->getRegByName("r30");
259     insnCodeGen::saveRegister(gen, linkRegister, -2*GPRSIZE_64);
260
261     //Save frame pointer
262     Register framePointer = gen.rs()->getRegByName("r29");
263     insnCodeGen::saveRegister(gen, framePointer, -2*GPRSIZE_64);
264
265     //Move stack pointer to frame pointer
266     Register stackPointer = gen.rs()->getRegByName("sp");
267     insnCodeGen::generateMoveSP(gen, stackPointer, framePointer, true);
268 }
269
270 /***********************************************************************************************/
271 /***********************************************************************************************/
272
273 /********************************* EmitterAARCH64RestoreRegs ************************************/
274
275 /********************************* Public methods *********************************************/
276
277 unsigned EmitterAARCH64RestoreRegs::restoreGPRegisters(
278         codeGen &gen, registerSpace *theRegSpace, int offset)
279 {
280     unsigned ret = 0;
281
282     for(int idx = theRegSpace->numGPRs()-1; idx >=0; idx--) {
283         registerSlot *reg = theRegSpace->GPRs()[idx];
284
285         if(reg->liveState == registerSlot::spilled) {
286             //#sasha this should be GPRSIZE_64 and not gen.width
287             int offset_from_sp = offset + (reg->encoding() * gen.width());
288             insnCodeGen::restoreRegister(gen, reg->number, offset_from_sp);
289             ret++;
290         }
291     }
292
293     return ret;
294 }
295
296 unsigned EmitterAARCH64RestoreRegs::restoreFPRegisters(
297         codeGen &gen, registerSpace *theRegSpace, int offset)
298 {
299     unsigned ret = 0;
300
301     for(int idx = theRegSpace->numFPRs() - 1; idx >= 0; idx--) {
302         registerSlot *reg = theRegSpace->FPRs()[idx];
303
304         //if(reg->liveState == registerSlot::spilled) {
305             int offset_from_sp = offset + (reg->encoding() * FPRSIZE_64);
306             restoreFPRegister(gen, reg->number, offset_from_sp);
307             ret++;
308         //}
309     }
310
311     return ret;
312 }
313
314 unsigned EmitterAARCH64RestoreRegs::restoreSPRegisters(
315         codeGen &gen, registerSpace *theRegSpace, int offset, int force_save)
316 {
317     int ret = 0;
318
319     std::vector<registerSlot *> spRegs;
320     map<registerSlot *, int> regMap;
321
322     registerSlot *regNzcv = (*theRegSpace)[registerSpace::pstate];
323     assert(regNzcv);
324     regMap[regNzcv] = SPR_NZCV;
325     if(force_save || regNzcv->liveState == registerSlot::spilled)
326         spRegs.push_back(regNzcv);
327
328     registerSlot *regFpcr = (*theRegSpace)[registerSpace::fpcr];
329     assert(regFpcr);
330     regMap[regFpcr] = SPR_FPCR;
331     if(force_save || regFpcr->liveState == registerSlot::spilled)
332         spRegs.push_back(regFpcr);
333
334     registerSlot *regFpsr = (*theRegSpace)[registerSpace::fpsr];
335     assert(regFpsr);
336     regMap[regFpsr] = SPR_FPSR;
337     if(force_save || regFpsr->liveState == registerSlot::spilled)
338         spRegs.push_back(regFpsr);
339
340     for(std::vector<registerSlot *>::iterator itr = spRegs.begin(); itr != spRegs.end(); itr++) {
341         registerSlot *cur = *itr;
342         restoreSPR(gen, theRegSpace->getScratchRegister(gen, true), regMap[cur], 4*GPRSIZE_32);
343         ret++;
344     }
345
346     return ret;
347 }
348
349 void EmitterAARCH64RestoreRegs::tearFrame(codeGen &gen) {
350     //Restore frame pointer
351     Register framePointer = gen.rs()->getRegByName("r29");
352     insnCodeGen::restoreRegister(gen, framePointer, 2*GPRSIZE_64);
353
354     //Restore link register
355     Register linkRegister = gen.rs()->getRegByName("r30");
356     insnCodeGen::restoreRegister(gen, linkRegister, 2*GPRSIZE_64);
357 }
358
359
360 /********************************* Private methods *********************************************/
361
362 void EmitterAARCH64RestoreRegs::restoreSPR(codeGen &gen, Register scratchReg, int sprnum, int stkOffset)
363 {
364     insnCodeGen::generateMemAccess32or64(gen, insnCodeGen::Load, scratchReg, REG_SP, stkOffset, false);
365
366     //TODO move map to common location
367     map<int, int> sysRegCodeMap = map_list_of(SPR_NZCV, 0x5A10)(SPR_FPCR, 0x5A20)(SPR_FPSR, 0x5A21);
368     if (!sysRegCodeMap.count(sprnum))
369         assert(!"Invalid/unknown system register passed to restoreSPR()!");
370
371     instruction insn;
372     insn.clear();
373
374     //Set opcode for MSR (register) instruction
375     INSN_SET(insn, 20, 31, MSROp);
376     //Set source register
377     INSN_SET(insn, 0, 4, scratchReg & 0x1F);
378     //Set bits representing destination system register
379     INSN_SET(insn, 5, 19, sysRegCodeMap[sprnum]);
380     insnCodeGen::generate(gen, insn);
381 }
382
383 void EmitterAARCH64RestoreRegs::restoreFPRegister(codeGen &gen, Register reg, int save_off) {
384     insnCodeGen::generateMemAccessFP(gen, insnCodeGen::Load, reg, REG_SP, save_off, 0, true);
385 }
386
387 /***********************************************************************************************/
388 /***********************************************************************************************/
389
390 /*
391  * Emit code to push down the stack
392  */
393 void pushStack(codeGen &gen)
394 {
395     if (gen.width() == 8)
396         insnCodeGen::generateAddSubImmediate(gen, insnCodeGen::Sub, 0,
397                 TRAMP_FRAME_SIZE_64, REG_SP, REG_SP, true);
398     else
399         assert(0); // 32 bit not implemented
400 }
401
402 void popStack(codeGen &gen)
403 {
404     if (gen.width() == 8)
405         insnCodeGen::generateAddSubImmediate(gen, insnCodeGen::Add, 0,
406                 TRAMP_FRAME_SIZE_64, REG_SP, REG_SP, true);
407     else
408         assert(0); // 32 bit not implemented
409 }
410
411 /*********************************** Base Tramp ***********************************************/
412 bool baseTramp::generateSaves(codeGen &gen, registerSpace *)
413 {
414     regalloc_printf("========== baseTramp::generateSaves\n");
415
416     // Make a stack frame.
417     pushStack(gen);
418
419     EmitterAARCH64SaveRegs saveRegs;
420     unsigned int width = gen.width();
421
422     saveRegs.saveGPRegisters(gen, gen.rs(), TRAMP_GPR_OFFSET(width));
423
424     bool saveFPRs = BPatch::bpatch->isForceSaveFPROn() ||
425                    (BPatch::bpatch->isSaveFPROn()      &&
426                     gen.rs()->anyLiveFPRsAtEntry()     &&
427                     this->saveFPRs());
428
429     if(saveFPRs) saveRegs.saveFPRegisters(gen, gen.rs(), TRAMP_FPR_OFFSET(width));
430     this->savedFPRs = saveFPRs;
431
432     saveRegs.saveSPRegisters(gen, gen.rs(), TRAMP_SPR_OFFSET(width), false);
433     //gen.rs()->debugPrint();
434
435     return true;
436 }
437
438 bool baseTramp::generateRestores(codeGen &gen, registerSpace *)
439 {
440     EmitterAARCH64RestoreRegs restoreRegs;
441     unsigned int width = gen.width();
442
443     restoreRegs.restoreSPRegisters(gen, gen.rs(), TRAMP_SPR_OFFSET(width), false);
444
445     if(this->savedFPRs)
446         restoreRegs.restoreFPRegisters(gen, gen.rs(), TRAMP_FPR_OFFSET(width));
447
448     restoreRegs.restoreGPRegisters(gen, gen.rs(), TRAMP_GPR_OFFSET(width));
449
450     // Tear down the stack frame.
451     popStack(gen);
452
453     return true;
454 }
455
456 /***********************************************************************************************/
457 /***********************************************************************************************/
458
459 //TODO: 32-/64-bit regs?
460 void emitImm(opCode op, Register src1, RegValue src2imm, Register dest, 
461         codeGen &gen, bool /*noCost*/, registerSpace * /* rs */)
462 {
463     switch(op) {
464         case plusOp:
465         case minusOp:
466             {
467                 Register rm = insnCodeGen::moveValueToReg(gen, src2imm);
468                 insnCodeGen::generateAddSubShifted(gen,
469                         op == plusOp ? insnCodeGen::Add : insnCodeGen::Sub,
470                         0, 0, rm, src1, dest, true);
471             }
472             break;
473         case timesOp:
474             {
475                 Register rm = insnCodeGen::moveValueToReg(gen, src2imm);
476                 insnCodeGen::generateMul(gen, rm, src1, dest, true);
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         case branchOp:
702             {
703                 insnCodeGen::generateBranch(gen, dest);
704                 retval = gen.getIndex();
705                 break;
706             }
707         default:
708             assert(0);        // op not implemented or not expected for this emit!
709     }
710
711     return retval;
712 }
713
714 Register emitR(opCode op, Register src1, Register src2, Register dest,
715                codeGen &gen, bool /*noCost*/,
716                const instPoint * location, bool /*for_MT*/)
717 {
718     registerSlot *regSlot = NULL;
719     unsigned addrWidth = gen.width();
720
721     switch(op){
722         case getRetValOp:
723             regSlot = (*(gen.rs()))[registerSpace::r0];
724             break;
725         case getParamOp:
726             // src1 is the number of the argument
727             // dest is a register where we can store the value
728             //gen.codeEmitter()->emitGetParam(dest, src1, location->type(), op,
729             //        false, gen);
730
731             if(src1 <= 7) {
732                 // src1 is 0..7 - it's a parameter order number, not a register
733                 regSlot = (*(gen.rs()))[registerSpace::r0 + src1];
734                 break;
735
736             } else {
737                 assert(0);
738             }
739             break;
740         default:
741             assert(0);
742     }
743
744     assert(regSlot);
745     Register reg = regSlot->number;
746
747     switch(regSlot->liveState) {
748         case registerSlot::spilled:
749             {
750                 int offset = TRAMP_GPR_OFFSET(addrWidth);
751                 // its on the stack so load it.
752                 //if (src2 != REG_NULL) saveRegister(gen, src2, reg, offset);
753                 insnCodeGen::restoreRegister(gen, dest, offset + (reg * gen.width()));
754                 return(dest);
755             }
756         case registerSlot::live:
757             {
758                 // its still in a register so return the register it is in.
759                 cerr << "emitR state:" << reg << " live" << endl;
760                 assert(0);
761                 return(reg);
762             }
763         case registerSlot::dead:
764             {
765                 cerr << "emitR state" << reg << ": dead" << endl;
766                 // Uhhh... wha?
767                 assert(0);
768             }
769     }
770     return reg;
771 }
772
773 void emitJmpMC(int /*condition*/, int /*offset*/, codeGen &) {
774     assert(0); //Not implemented
775     // Not needed for memory instrumentation, otherwise TBD
776 }
777
778
779 // VG(11/16/01): Say if we have to restore a register to get its original value
780 // VG(03/15/02): Sync'd with the new AIX tramp
781 static inline bool needsRestore(Register x) {
782     assert(0); //Not implemented
783     return false;
784 }
785
786 // VG(03/15/02): Restore mutatee value of GPR reg to dest GPR
787 static inline void restoreGPRtoGPR(codeGen &gen,
788                                    Register reg, Register dest) {
789     assert(0); //Not implemented
790 }
791
792 // VG(03/15/02): Restore mutatee value of XER to dest GPR
793 static inline void restoreXERtoGPR(codeGen &gen, Register dest) {
794     assert(0); //Not implemented
795 }
796
797 // VG(03/15/02): Move bits 25:31 of GPR reg to GPR dest
798 static inline void moveGPR2531toGPR(codeGen &gen,
799                                     Register reg, Register dest) {
800     assert(0); //Not implemented
801 }
802
803 // VG(11/16/01): Emit code to add the original value of a register to
804 // another. The original value may need to be restored from stack...
805 // VG(03/15/02): Made functionality more obvious by adding the above functions
806 static inline void emitAddOriginal(Register src, Register acc,
807                                    codeGen &gen, bool noCost) {
808     assert(0); //Not implemented
809 }
810
811 // VG(11/07/01): Load in destination the effective address given
812 // by the address descriptor. Used for memory access stuff.
813 void emitASload(const BPatch_addrSpec_NP *as, Register dest, int stackShift,
814                 codeGen &gen,
815                 bool noCost) {
816     assert(0); //Not implemented
817 }
818
819 void emitCSload(const BPatch_addrSpec_NP *as, Register dest, codeGen &gen,
820                 bool noCost) {
821     assert(0); //Not implemented
822 }
823
824 void emitVload(opCode op, Address src1, Register src2, Register dest,
825                codeGen &gen, bool /*noCost*/,
826                registerSpace * /*rs*/, int size,
827                const instPoint * /* location */, AddressSpace *proc)
828 {
829     switch(op)
830     {
831         case loadConstOp:
832             // dest is a temporary
833             // src1 is an immediate value
834             // dest = src1:imm32
835             gen.codeEmitter()->emitLoadConst(dest, src1, gen);
836             break;
837         case loadOp:
838             // dest is a temporary
839             // src1 is the address of the operand
840             // dest = [src1]
841             gen.codeEmitter()->emitLoad(dest, src1, size, gen);
842             break;
843         case loadRegRelativeAddr:
844             // (readReg(src2) + src1)
845             // dest is a temporary
846             // src2 is the register
847             // src1 is the offset from the address in src2
848             gen.codeEmitter()->emitLoadOrigRegRelative(dest, src1, src2, gen, false);
849             break;
850         case loadRegRelativeOp:
851             // *(readReg(src2) + src1)
852             // dest is a temporary
853             // src2 is the register
854             // src1 is the offset from the address in src2
855             gen.codeEmitter()->emitLoadOrigRegRelative(dest, src1, src2, gen, true);
856             break;
857         default:
858             assert(0); //Not implemented
859             break;
860     }
861 }
862
863 void emitVstore(opCode op, Register src1, Register /*src2*/, Address dest,
864         codeGen &gen, bool noCost,
865         registerSpace * /* rs */, int size,
866         const instPoint * /* location */, AddressSpace *proc)
867 {
868     if (op ==  storeOp) {
869         // [dest] = src1
870         // dest has the address where src1 is to be stored
871         // src1 is a temporary
872         // src2 is a "scratch" register, we don't need it in this architecture
873         gen.codeEmitter()->emitStore(dest, src1, size, gen);
874     }else{
875         assert(0); //Not implemented
876     }
877     return;
878 }
879
880 void emitV(opCode op, Register src1, Register src2, Register dest,
881         codeGen &gen, bool /*noCost*/,
882            registerSpace * /*rs*/, int size,
883            const instPoint * /* location */, AddressSpace *proc) 
884 {
885     switch(op){
886         case plusOp:
887         case minusOp:
888         case divOp:
889         case timesOp:
890         case orOp:
891         case andOp:
892         case xorOp:
893             gen.codeEmitter()->emitOp(op, dest, src1, src2, gen);
894             break;
895         case lessOp:
896         case leOp:
897         case greaterOp:
898         case geOp:
899         case eqOp:
900         case neOp:
901             gen.codeEmitter()->emitRelOp(op, dest, src1, src2, gen);
902             break;
903         case loadIndirOp:
904             size = !size ? proc->getAddressWidth() : size;
905             // same as loadOp, but the value to load is already in a register
906             gen.codeEmitter()->emitLoadIndir(dest, src1, size, gen);
907             break;
908         case storeIndirOp:
909             size = !size ? proc->getAddressWidth() : size;
910             gen.codeEmitter()->emitStoreIndir(dest, src1, size, gen);
911             break;
912         default:
913             //std::cout << "operation not implemented= " << op << endl;
914             assert(0); // Not implemented
915             break;
916     }
917     return;
918 }
919
920 //
921 // I don't know how to compute cycles for AARCH64 instructions due to
922 //   multiple functional units.  However, we can compute the number of
923 //   instructions and hope that is fairly close. - jkh 1/30/96
924 //
925 int getInsnCost(opCode op) {
926     assert(0); //Not implemented
927     return NULL;
928 }
929
930 #if 0
931 // What does this do???
932 void registerSpace::saveClobberInfo(const instPoint *location)
933 {
934   registerSlot *regSlot = NULL;
935   registerSlot *regFPSlot = NULL;
936   if (location == NULL)
937     return;
938   if (location->actualGPRLiveSet_ != NULL && location->actualFPRLiveSet_ != NULL)
939     {
940
941       // REG guard registers, if live, must be saved
942       if (location->actualGPRLiveSet_[ REG_GUARD_ADDR ] == LIVE_REG)
943     location->actualGPRLiveSet_[ REG_GUARD_ADDR ] = LIVE_CLOBBERED_REG;
944
945       if (location->actualGPRLiveSet_[ REG_GUARD_OFFSET ] == LIVE_REG)
946     location->actualGPRLiveSet_[ REG_GUARD_OFFSET ] = LIVE_CLOBBERED_REG;
947
948       // GPR and FPR scratch registers, if live, must be saved
949       if (location->actualGPRLiveSet_[ REG_SCRATCH ] == LIVE_REG)
950     location->actualGPRLiveSet_[ REG_SCRATCH ] = LIVE_CLOBBERED_REG;
951
952       if (location->actualFPRLiveSet_[ REG_SCRATCH ] == LIVE_REG)
953     location->actualFPRLiveSet_[ REG_SCRATCH ] = LIVE_CLOBBERED_REG;
954
955       // Return func call register, since we make a call because
956       // of multithreading (regardless if it's threaded) from BT
957       // we must save return register
958       if (location->actualGPRLiveSet_[ 3 ] == LIVE_REG)
959     location->actualGPRLiveSet_[ 3 ] = LIVE_CLOBBERED_REG;
960
961
962       for (u_int i = 0; i < getRegisterCount(); i++)
963     {
964       regSlot = getRegSlot(i);
965
966       if (  location->actualGPRLiveSet_[ (int) registers[i].number ] == LIVE_REG )
967         {
968           if (!registers[i].beenClobbered)
969         location->actualGPRLiveSet_[ (int) registers[i].number ] = LIVE_UNCLOBBERED_REG;
970           else
971         location->actualGPRLiveSet_[ (int) registers[i].number ] = LIVE_CLOBBERED_REG;
972         }
973
974
975       if (  location->actualGPRLiveSet_[ (int) registers[i].number ] == LIVE_UNCLOBBERED_REG )
976         {
977           if (registers[i].beenClobbered)
978         location->actualGPRLiveSet_[ (int) registers[i].number ] = LIVE_CLOBBERED_REG;
979         }
980     }
981
982       for (u_int i = 0; i < getFPRegisterCount(); i++)
983     {
984       regFPSlot = getFPRegSlot(i);
985
986       if (  location->actualFPRLiveSet_[ (int) fpRegisters[i].number ] == LIVE_REG )
987         {
988           if (!fpRegisters[i].beenClobbered)
989         location->actualFPRLiveSet_[ (int) fpRegisters[i].number ] = LIVE_UNCLOBBERED_REG;
990           else
991         location->actualFPRLiveSet_[ (int) fpRegisters[i].number ] = LIVE_CLOBBERED_REG;
992         }
993
994       if (  location->actualFPRLiveSet_[ (int) fpRegisters[i].number ] == LIVE_UNCLOBBERED_REG )
995         {
996           if (fpRegisters[i].beenClobbered)
997         location->actualFPRLiveSet_[ (int) fpRegisters[i].number ] = LIVE_CLOBBERED_REG;
998         }
999     }
1000     }
1001 }
1002 #endif
1003
1004 // This is used for checking wether immediate value should be encoded
1005 // into a instruction. In fact, only being used for loading constant
1006 // value into a register, and in ARMv8 there are 16 bits for immediate
1007 // values in the instruction MOV.
1008 // value here is never a negative value since constant values are saved
1009 // as void* in the AST operand.
1010 bool doNotOverflow(int64_t value)
1011 {
1012     if ((value >= 0) && (value <= 0xFFFF)) return true;
1013     else return false;
1014 }
1015
1016
1017 #if !defined(os_vxworks)
1018
1019 // hasBeenBound: returns true if the runtime linker has bound the
1020 // function symbol corresponding to the relocation entry in at the address
1021 // specified by entry and base_addr.  If it has been bound, then the callee
1022 // function is returned in "target_pdf", else it returns false.
1023 bool PCProcess::hasBeenBound(const SymtabAPI::relocationEntry &entry,
1024                              func_instance *&target_pdf, Address base_addr)
1025 {
1026         if (isTerminated()) return false;
1027
1028         // if the relocationEntry has not been bound yet, then the value
1029         // at rel_addr is the address of the instruction immediately following
1030         // the first instruction in the PLT entry (which is at the target_addr)
1031         // The PLT entries are never modified, instead they use an indirrect
1032         // jump to an address stored in the _GLOBAL_OFFSET_TABLE_.  When the
1033         // function symbol is bound by the runtime linker, it changes the address
1034         // in the _GLOBAL_OFFSET_TABLE_ corresponding to the PLT entry
1035
1036         Address got_entry = entry.rel_addr() + base_addr;
1037         Address bound_addr = 0;
1038         if (!readDataSpace((const void*)got_entry, sizeof(Address),
1039                                 &bound_addr, true)){
1040                 sprintf(errorLine, "read error in PCProcess::hasBeenBound addr 0x%x, pid=%d\n (readDataSpace returns 0)",(unsigned)got_entry,getPid());
1041                 logLine(errorLine);
1042                 //print_read_error_info(entry, target_pdf, base_addr);
1043                 fprintf(stderr, "%s[%d]: %s\n", FILE__, __LINE__, errorLine);
1044                 return false;
1045         }
1046
1047    //fprintf(stderr, "%s[%d]:  hasBeenBound:  %p ?= %p ?\n", FILE__, __LINE__, bound_addr, entry.target_addr() + 6 + base_addr);
1048         if ( !( bound_addr == (entry.target_addr()+6+base_addr)) ) {
1049           // the callee function has been bound by the runtime linker
1050           // find the function and return it
1051           target_pdf = findFuncByEntry(bound_addr);
1052           if(!target_pdf){
1053             return false;
1054           }
1055           return true;
1056         }
1057         return false;
1058 }
1059
1060 #endif
1061
1062 bool PCProcess::bindPLTEntry(const SymtabAPI::relocationEntry &, Address,
1063                              func_instance *, Address) {
1064     assert(0); //Not implemented
1065     assert(0 && "TODO!");
1066     return false;
1067 }
1068
1069 void emitLoadPreviousStackFrameRegister(Address register_num,
1070                                         Register dest,
1071                                         codeGen &gen,
1072                                         int /*size*/,
1073                                         bool noCost)
1074 {
1075     gen.codeEmitter()->emitLoadOrigRegister(register_num, dest, gen);
1076 }
1077
1078 void emitStorePreviousStackFrameRegister(Address,
1079                                          Register,
1080                                          codeGen &,
1081                                          int,
1082                                          bool) {
1083     assert(0);
1084 }
1085
1086 // First AST node: target of the call
1087 // Second AST node: source of the call
1088 // This can handle indirect control transfers as well
1089 bool AddressSpace::getDynamicCallSiteArgs(InstructionAPI::Instruction i,
1090                                           Address addr,
1091                                           pdvector<AstNodePtr> &args)
1092 {
1093     using namespace Dyninst::InstructionAPI;
1094     Register branch_target = registerSpace::ignored;
1095
1096     for(Instruction::cftConstIter curCFT = i.cft_begin();
1097             curCFT != i.cft_end(); ++curCFT)
1098     {
1099         auto target_reg = dynamic_cast<RegisterAST *>(curCFT->target.get());
1100         if(!target_reg) return false;
1101         branch_target = target_reg->getID() & 0x1f;
1102         break;
1103     }
1104
1105     if(branch_target == registerSpace::ignored) return false;
1106
1107     //jumping to Xn (BLR Xn)
1108     args.push_back(AstNode::operandNode(AstNode::origRegister,(void *) branch_target));
1109     args.push_back(AstNode::operandNode(AstNode::Constant, (void *) addr));
1110
1111     //inst_printf("%s[%d]:  Inserting dynamic call site instrumentation for %s\n",
1112     //        FILE__, __LINE__, cft->format(insn.getArch()).c_str());
1113     return true;
1114 }
1115
1116 bool writeFunctionPtr(AddressSpace *p, Address addr, func_instance *f) {
1117     Address val_to_write = f->addr();
1118     return p->writeDataSpace((void *) addr, sizeof(Address), &val_to_write);
1119     return false;
1120 }
1121
1122 Emitter *AddressSpace::getEmitter() {
1123     static EmitterAARCH64Stat emitter64Stat;
1124     static EmitterAARCH64Dyn emitter64Dyn;
1125
1126     if (proc())
1127         return &emitter64Dyn;
1128
1129     return &emitter64Stat;
1130 }
1131
1132 #define GET_IP      0x429f0005
1133 #define MFLR_30     0x7fc802a6
1134 #define ADDIS_30_30 0x3fde0000
1135 #define ADDI_30_30  0x3bde0000
1136 #define LWZ_11_30   0x817e0000
1137 #define ADDIS_11_30 0x3d7e0000
1138
1139 /*
1140  * If the target stub_addr is a glink stub, try to determine the actual
1141  * function called (through the GOT) and fill in that information.
1142  *
1143  * The function at stub_addr may not have been created when this method
1144  * is called.
1145  *
1146  * XXX Is this a candidate to move into general parsing code, or is
1147  *     this properly a Dyninst-only technique?
1148  */
1149
1150 /*
1151 bool image::updatePltFunc(parse_func *caller_func, Address stub_addr)
1152 {
1153         assert(0); //Not implemented
1154     return true;
1155 }
1156 */
1157
1158 bool EmitterAARCH64::emitCallRelative(Register dest, Address offset, Register base, codeGen &gen) {
1159     assert(0); //Not implemented
1160     return true;
1161 }
1162
1163 bool EmitterAARCH64::emitLoadRelative(Register dest, Address offset, Register base, int size, codeGen &gen) {
1164     assert(0); //Not implemented
1165     return true;
1166 }
1167
1168
1169 void EmitterAARCH64::emitStoreRelative(Register source, Address offset, Register base, int size, codeGen &gen) {
1170     //return true;
1171     assert(0); //Not implemented
1172 }
1173
1174 bool EmitterAARCH64::emitMoveRegToReg(registerSlot *src,
1175                                       registerSlot *dest,
1176                                       codeGen &gen) {
1177     assert(0); //Not implemented
1178     return true;
1179 }
1180
1181 /*
1182 bool EmitterAARCH6432Stat::emitPIC(codeGen& gen, Address origAddr, Address relocAddr) {
1183
1184       Register scratchPCReg = gen.rs()->getScratchRegister(gen, true);
1185       std::vector<Register> excludeReg;
1186       excludeReg.push_back(scratchPCReg);
1187       Register scratchReg = gen.rs()->getScratchRegister(gen, excludeReg, true);
1188       bool newStackFrame = false;
1189       int stack_size = 0;
1190       int gpr_off, fpr_off, ctr_off;
1191       //fprintf(stderr, " emitPIC origAddr 0x%lx reloc 0x%lx Registers PC %d scratch %d \n", origAddr, relocAddr, scratchPCReg, scratchReg);
1192       if ((scratchPCReg == REG_NULL) || (scratchReg == REG_NULL)) {
1193                 //fprintf(stderr, " Creating new stack frame for 0x%lx to 0x%lx \n", origAddr, relocAddr);
1194
1195                 newStackFrame = true;
1196                 //create new stack frame
1197                 gpr_off = TRAMP_GPR_OFFSET_32;
1198                 fpr_off = TRAMP_FPR_OFFSET_32;
1199                 ctr_off = STK_CTR_32;
1200
1201                 // Make a stack frame.
1202                 pushStack(gen);
1203
1204                 // Save GPRs
1205               stack_size = saveGPRegisters(gen, gen.rs(), gpr_off, 2);
1206
1207               scratchPCReg = gen.rs()->getScratchRegister(gen, true);
1208               assert(scratchPCReg != REG_NULL);
1209               excludeReg.clear();
1210               excludeReg.push_back(scratchPCReg);
1211               scratchReg = gen.rs()->getScratchRegister(gen, excludeReg, true);
1212               assert(scratchReg != REG_NULL);
1213               // relocaAddr has moved since we added instructions to setup a new stack frame
1214               relocAddr = relocAddr + ((stack_size + 1)*(gen.width()));
1215               //fprintf(stderr, " emitPIC origAddr 0x%lx reloc 0x%lx stack size %d Registers PC %d scratch %d \n", origAddr, relocAddr, stack_size, scratchPCReg, scratchReg);
1216
1217         }
1218         emitMovePCToReg(scratchPCReg, gen);
1219         Address varOffset = origAddr - relocAddr;
1220         emitCallRelative(scratchReg, varOffset, scratchPCReg, gen);
1221         insnCodeGen::generateMoveToLR(gen, scratchReg);
1222         if(newStackFrame) {
1223               // GPRs
1224               restoreGPRegisters(gen, gen.rs(), gpr_off);
1225               popStack(gen);
1226         }
1227
1228       return 0;
1229 }
1230
1231 bool EmitterAARCH64Stat::emitPIC(codeGen& gen, Address origAddr, Address relocAddr) {
1232         assert(0);
1233         return false;
1234 }
1235 bool EmitterAARCH64Dyn::emitPIC(codeGen &gen, Address origAddr, Address relocAddr) {
1236
1237         Address origRet = origAddr + 4;
1238         Register scratch = gen.rs()->getScratchRegister(gen, true);
1239         assert(scratch != REG_NULL);
1240         instruction::loadImmIntoReg(gen, scratch, origRet);
1241         insnCodeGen::generateMoveToLR(gen, scratch);
1242         return true;
1243
1244 }
1245 */
1246
1247 bool EmitterAARCH64Stat::emitPLTCommon(func_instance *callee, bool call, codeGen &gen) {
1248     assert(0); //Not implemented
1249     return true;
1250 }
1251
1252 #if 0
1253 bool EmitterAARCH64Stat::emitPLTCommon(func_instance *callee, bool call, codeGen &gen) {
1254   // In PPC64 Linux, function descriptors are used in place of direct
1255   // function pointers.  The descriptors have the following layout:
1256   //
1257   // Function Descriptor --> + 0: <Function Text Address>
1258   //                         + 8: <TOC Pointer Value>
1259   //                         +16: <Environment Pointer [Optional]>
1260   //
1261   // Additionally, this should be able to stomp on the link register (LR)
1262   // and TOC register (r2), as they were saved by Emitter::emitCall() if
1263   // necessary.
1264   //
1265   // So here's a brief sketch of the code this function generates:
1266   //
1267   //   Set up new branch target in LR from function descriptor
1268   //   Set up new TOC in R2 from function descriptor + 8
1269   //   Call
1270   bool isStaticBinary = false;
1271
1272   if(gen.addrSpace()->edit()->getMappedObject()->parse_img()->getObject()->isStaticBinary()) {
1273     isStaticBinary = true;
1274   }
1275
1276   const unsigned TOCreg = 2;
1277   const unsigned wordsize = gen.width();
1278   assert(wordsize == 8);
1279   Address dest = getInterModuleFuncAddr(callee, gen);
1280   Address caller_toc = 0;
1281   Address toc_anchor = gen.addrSpace()->getTOCoffsetInfo(callee);
1282   // Instead of saving the TOC (if we can't), just reset it afterwards.
1283   if (gen.func()) {
1284     caller_toc = gen.addrSpace()->getTOCoffsetInfo(gen.func());
1285   }
1286   else if (gen.point()) {
1287     caller_toc = gen.addrSpace()->getTOCoffsetInfo(gen.point()->func());
1288   }
1289   else {
1290     // Don't need it, and this might be an iRPC
1291   }
1292
1293   if(isStaticBinary)
1294     caller_toc = 0;
1295
1296   //Offset destOff = dest - gen.currAddr();
1297   Offset destOff = dest - caller_toc;
1298
1299   //    insnCodeGen::loadPartialImmIntoReg(gen, TOCreg, destOff);
1300   // Broken to see if any of this generates intellible code.
1301
1302   Register scratchReg = 3; // = gen.rs()->getScratchRegister(gen, true);
1303   int stackSize = 0;
1304   if (scratchReg == REG_NULL) {
1305     std::vector<Register> freeReg;
1306     std::vector<Register> excludeReg;
1307     stackSize = insnCodeGen::createStackFrame(gen, 1, freeReg, excludeReg);
1308     assert (stackSize == 1);
1309     scratchReg = freeReg[0];
1310   }
1311   insnCodeGen::loadImmIntoReg<Offset?(gen, scratchReg, destOff);
1312
1313   if(!isStaticBinary) {
1314     insnCodeGen::generateLoadReg64(gen, scratchReg, scratchReg, TOCreg);
1315
1316     insnCodeGen::generateMemAccess64(gen, LDop, LDxop,
1317                      TOCreg, scratchReg, 8);
1318   }
1319   insnCodeGen::generateMemAccess64(gen, LDop, LDxop,
1320                    scratchReg, scratchReg, 0);
1321
1322   insnCodeGen::generateMoveToCR(gen, scratchReg);
1323
1324   if (stackSize > 0)
1325     insnCodeGen::removeStackFrame(gen);
1326
1327
1328   instruction branch_insn(call ? BCTRLraw : BCTRraw);
1329   insnCodeGen::generate(gen, branch_insn);
1330
1331   return true;
1332 }
1333 #endif
1334
1335 bool EmitterAARCH64Dyn::emitTOCCommon(block_instance *block, bool call, codeGen &gen) {
1336     assert(0); //Not implemented
1337     return true;
1338 }
1339
1340 // TODO 32/64-bit?
1341 bool EmitterAARCH64Stat::emitPLTCall(func_instance *callee, codeGen &gen) {
1342     assert(0); //Not implemented
1343     return emitPLTCommon(callee, true, gen);
1344 }
1345
1346 bool EmitterAARCH64Stat::emitPLTJump(func_instance *callee, codeGen &gen) {
1347     assert(0); //Not implemented
1348     return emitPLTCommon(callee, false, gen);
1349 }
1350
1351 bool EmitterAARCH64Stat::emitTOCCall(block_instance *block, codeGen &gen) {
1352     assert(0); //Not implemented
1353     return emitTOCCommon(block, true, gen);
1354 }
1355
1356 bool EmitterAARCH64Stat::emitTOCJump(block_instance *block, codeGen &gen) {
1357     assert(0); //Not implemented
1358     return emitTOCCommon(block, false, gen);
1359 }
1360
1361 bool EmitterAARCH64Stat::emitTOCCommon(block_instance *block, bool call, codeGen &gen) {
1362     assert(0); //Not implemented
1363     return false;
1364 }
1365
1366 bool EmitterAARCH64Stat::emitCallInstruction(codeGen &gen,
1367                                              func_instance *callee,
1368                                              bool setTOC, Address) {
1369     assert(0); //Not implemented
1370     return true;
1371 }
1372
1373 // Generates call instruction sequence for all AARCH64-based systems
1374 // under dynamic instrumentation.
1375 //
1376 // This should be able to stomp on the link register (LR) and TOC
1377 // register (r2), as they were saved by Emitter::emitCall() as necessary.
1378 bool EmitterAARCH64::emitCallInstruction(codeGen &gen, func_instance *callee, bool setTOC, Address toc_anchor) {
1379     assert(0); //Not implemented
1380     return true;
1381 }
1382
1383 void EmitterAARCH64::emitLoadShared(opCode op, Register dest, const image_variable *var, bool is_local, int size,
1384                                     codeGen &gen, Address offset) {
1385     assert(0); //Not implemented
1386     return;
1387 }
1388
1389 void
1390 EmitterAARCH64::emitStoreShared(Register source, const image_variable *var, bool is_local, int size, codeGen &gen) {
1391     assert(0); //Not implemented
1392     return;
1393 }
1394
1395 Address Emitter::getInterModuleVarAddr(const image_variable *var, codeGen &gen) {
1396     assert(0); //Not implemented
1397     AddressSpace *addrSpace = gen.addrSpace();
1398     if (!addrSpace)
1399         assert(0 && "No AddressSpace associated with codeGen object");
1400
1401     BinaryEdit *binEdit = addrSpace->edit();
1402     Address relocation_address;
1403     return relocation_address;
1404 }
1405
1406 Address EmitterAARCH64::emitMovePCToReg(Register dest, codeGen &gen) {
1407     assert(0); //Not implemented
1408     insnCodeGen::generateBranch(gen, gen.currAddr(), gen.currAddr() + 4, true); // blrl
1409     Address ret = gen.currAddr();
1410     return ret;
1411 }
1412
1413 Address Emitter::getInterModuleFuncAddr(func_instance *func, codeGen &gen) {
1414     assert(0); //Not implemented
1415     return NULL;
1416 }
1417
1418
1419
1420