ARMv8 initial work on rewriter (#612)
[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 #include "common/src/headers.h"
32 #include "dyninstAPI/h/BPatch_memoryAccess_NP.h"
33 #include "dyninstAPI/src/image.h"
34 #include "dyninstAPI/src/dynProcess.h"
35 #include "dyninstAPI/src/inst.h"
36 #include "dyninstAPI/src/instP.h"
37 #include "dyninstAPI/src/inst-aarch64.h"
38 #include "common/src/arch.h"
39 #include "dyninstAPI/src/codegen.h"
40 #include "dyninstAPI/src/ast.h"
41 #include "dyninstAPI/src/util.h"
42 #include "common/src/stats.h"
43 #include "dyninstAPI/src/os.h"
44 #include "dyninstAPI/src/instPoint.h" // class instPoint
45 #include "dyninstAPI/src/debug.h"
46 #include "common/src/debugOstream.h"
47 #include "dyninstAPI/src/baseTramp.h"
48 #include "dyninstAPI/h/BPatch.h"
49 #include "dyninstAPI/src/BPatch_collections.h"
50 #include "dyninstAPI/src/registerSpace.h"
51 #include "dyninstAPI/src/binaryEdit.h"
52 #include "dyninstAPI/src/function.h"
53 #include "dyninstAPI/src/mapped_object.h"
54
55 #include "parseAPI/h/CFG.h"
56
57 #include "emitter.h"
58 #include "emit-aarch64.h"
59
60 #include <boost/assign/list_of.hpp>
61 using namespace boost::assign;
62 #include <sstream>
63
64 #include "dyninstAPI/h/BPatch_memoryAccess_NP.h"
65
66 extern bool isPowerOf2(int value, int &result);
67
68 #define DISTANCE(x, y)   ((x<y) ? (y-x) : (x-y))
69
70 Address getMaxBranch() {
71     return MAX_BRANCH_OFFSET;
72 }
73
74 std::unordered_map<std::string, unsigned> funcFrequencyTable;
75
76 void initDefaultPointFrequencyTable() {
77     assert(0); //Not implemented
78 }
79
80 /************************************* Register Space **************************************/
81
82 void registerSpace::initialize32() {
83     assert(!"No 32-bit implementation for the ARM architecture!");
84 }
85
86 void registerSpace::initialize64() {
87     static bool done = false;
88     if (done)
89         return;
90
91     std::vector < registerSlot * > registers;
92
93     //GPRs
94     for (unsigned idx = r0; idx <= r28; idx++) {
95         char name[32];
96         if (idx < 10)
97             sprintf(name, "r%1d", idx - r0);
98         else
99             sprintf(name, "r%2d", idx - r0);
100         registers.push_back(new registerSlot(idx,
101                                              name,
102                                              false,
103                                              registerSlot::liveAlways,
104                                              registerSlot::GPR));
105     }
106     //Mark r29 (frame pointer) and r30 (link register) as off-limits
107     registers.push_back(new registerSlot(r29, "r29", true, registerSlot::liveAlways, registerSlot::GPR));
108     registers.push_back(new registerSlot(r30, "r30", true, registerSlot::liveAlways, registerSlot::GPR));
109
110     //SPRs
111     registers.push_back(new registerSlot(lr, "lr", true, registerSlot::liveAlways, registerSlot::SPR));
112     registers.push_back(new registerSlot(sp, "sp", true, registerSlot::liveAlways, registerSlot::SPR));
113     registers.push_back(new registerSlot(pstate, "nzcv", true, registerSlot::liveAlways, registerSlot::SPR));
114     registers.push_back(new registerSlot(fpcr, "fpcr", true, registerSlot::liveAlways, registerSlot::SPR));
115     registers.push_back(new registerSlot(fpsr, "fpsr", true, registerSlot::liveAlways, registerSlot::SPR));
116
117     //FPRs
118     for (unsigned idx = fpr0; idx <= fpr31; idx++) {
119         char name[32];
120         sprintf(name, "fpr%d", idx - fpr0);
121         registers.push_back(new registerSlot(idx,
122                                              name,//TODO mov SP to FP
123                                              false,
124                                              registerSlot::liveAlways,
125                                              registerSlot::FPR));
126     }
127
128     registerSpace::createRegisterSpace64(registers);
129     done = true;
130 }
131
132 void registerSpace::initialize() {
133     initialize64();
134 }
135
136 /************************************************************************************************/
137 /************************************************************************************************/
138
139 /********************************* EmitterAARCH64SaveRegs ***************************************/
140
141 /********************************* Private methods *********************************************/
142
143 void EmitterAARCH64SaveRegs::saveSPR(codeGen &gen, Register scratchReg, int sprnum, int stkOffset)
144 {
145     assert(scratchReg!=REG_NULL);
146
147     //TODO move map to common location
148     map<int, int> sysRegCodeMap = map_list_of(SPR_NZCV, 0x5A10)(SPR_FPCR, 0x5A20)(SPR_FPSR, 0x5A21);
149     if(!sysRegCodeMap.count(sprnum))
150         assert(!"Invalid/unknown system register passed to saveSPR()!");
151
152     instruction insn;
153     insn.clear();
154
155     //Set opcode for MRS instruction
156     INSN_SET(insn, 20, 31, MRSOp);
157     //Set destination register
158     INSN_SET(insn, 0, 4, scratchReg & 0x1F);
159     //Set bits representing source system register
160     INSN_SET(insn, 5, 19, sysRegCodeMap[sprnum]);
161     insnCodeGen::generate(gen, insn);
162
163     insnCodeGen::generateMemAccess(gen, insnCodeGen::Store, scratchReg,
164             REG_SP, stkOffset, 4, insnCodeGen::Pre);
165 }
166
167
168 void EmitterAARCH64SaveRegs::saveFPRegister(codeGen &gen, Register reg, int save_off) {
169     //Always performing save of the full FP register
170     insnCodeGen::generateMemAccessFP(gen, insnCodeGen::Store, reg, REG_SP, save_off, 0, true);
171
172 }
173
174 /********************************* Public methods *********************************************/
175
176 unsigned EmitterAARCH64SaveRegs::saveGPRegisters(
177         codeGen &gen, registerSpace *theRegSpace, int offset, int numReqGPRs)
178 {
179     int ret = 0;
180     if(numReqGPRs == -1) numReqGPRs = theRegSpace->numGPRs();
181
182     for(unsigned int idx = 0; idx < numReqGPRs; idx++) {
183         registerSlot *reg = theRegSpace->GPRs()[idx];
184         // We always save FP and LR for stack walking out of instrumentation
185         if (reg->liveState == registerSlot::live || reg->number == REG_FP || reg->number == REG_LR) {
186             int offset_from_sp = offset + (reg->encoding() * gen.width());
187             insnCodeGen::saveRegister(gen, reg->number, offset_from_sp);
188             theRegSpace->markSavedRegister(reg->number, offset_from_sp);
189             ret++;
190         }
191     }
192
193     return ret;
194 }
195
196 unsigned EmitterAARCH64SaveRegs::saveFPRegisters(
197         codeGen &gen, registerSpace *theRegSpace, int offset)
198 {
199     unsigned ret = 0;
200
201     for(int idx = 0; idx < theRegSpace->numFPRs(); idx++) {
202         registerSlot *reg = theRegSpace->FPRs()[idx];
203
204         //if(reg->liveState == registerSlot::live) {
205             int offset_from_sp = offset + (reg->encoding() * FPRSIZE_64);
206             saveFPRegister(gen, reg->number, offset_from_sp);
207             //reg->liveState = registerSlot::spilled;
208             theRegSpace->markSavedRegister(reg->number, offset_from_sp);
209             ret++;
210         //}
211     }
212
213     return ret;
214 }
215
216 unsigned EmitterAARCH64SaveRegs::saveSPRegisters(
217         codeGen &gen, registerSpace *theRegSpace, int offset, bool force_save)
218 {
219     int ret = 0;
220
221     std::vector<registerSlot *> spRegs;
222     map<registerSlot *, int> regMap;
223
224     registerSlot *regNzcv = (*theRegSpace)[registerSpace::pstate];
225     assert(regNzcv);
226     regMap[regNzcv] = SPR_NZCV;
227     if(force_save || regNzcv->liveState == registerSlot::live)
228         spRegs.push_back(regNzcv);
229
230     registerSlot *regFpcr = (*theRegSpace)[registerSpace::fpcr];
231     assert(regFpcr);
232     regMap[regFpcr] = SPR_FPCR;
233     if(force_save || regFpcr->liveState == registerSlot::live)
234         spRegs.push_back(regFpcr);
235
236     registerSlot *regFpsr = (*theRegSpace)[registerSpace::fpsr];
237     assert(regFpsr);
238     regMap[regFpsr] = SPR_FPSR;
239     if(force_save || regFpsr->liveState == registerSlot::live)
240         spRegs.push_back(regFpsr);
241
242     for(std::vector<registerSlot *>::iterator itr = spRegs.begin(); itr != spRegs.end(); itr++) {
243         registerSlot *cur = *itr;
244         saveSPR(gen, theRegSpace->getScratchRegister(gen, true), regMap[cur], -4*GPRSIZE_32);
245         theRegSpace->markSavedRegister(cur->number, offset);
246
247         offset += 4*GPRSIZE_32;
248         ret++;
249     }
250
251     return ret;
252 }
253
254 void EmitterAARCH64SaveRegs::createFrame(codeGen &gen) {
255     //Save link register
256     Register linkRegister = gen.rs()->getRegByName("r30");
257     insnCodeGen::saveRegister(gen, linkRegister, -2*GPRSIZE_64);
258
259     //Save frame pointer
260     Register framePointer = gen.rs()->getRegByName("r29");
261     insnCodeGen::saveRegister(gen, framePointer, -2*GPRSIZE_64);
262
263     //Move stack pointer to frame pointer
264     Register stackPointer = gen.rs()->getRegByName("sp");
265     insnCodeGen::generateMoveSP(gen, stackPointer, framePointer, true);
266 }
267
268 /***********************************************************************************************/
269 /***********************************************************************************************/
270
271 /********************************* EmitterAARCH64RestoreRegs ************************************/
272
273 /********************************* Public methods *********************************************/
274
275 unsigned EmitterAARCH64RestoreRegs::restoreGPRegisters(
276         codeGen &gen, registerSpace *theRegSpace, int offset)
277 {
278     unsigned ret = 0;
279
280     for(int idx = theRegSpace->numGPRs()-1; idx >=0; idx--) {
281         registerSlot *reg = theRegSpace->GPRs()[idx];
282
283         if(reg->liveState == registerSlot::spilled) {
284             //#sasha this should be GPRSIZE_64 and not gen.width
285             int offset_from_sp = offset + (reg->encoding() * gen.width());
286             insnCodeGen::restoreRegister(gen, reg->number, offset_from_sp);
287             ret++;
288         }
289     }
290
291     return ret;
292 }
293
294 unsigned EmitterAARCH64RestoreRegs::restoreFPRegisters(
295         codeGen &gen, registerSpace *theRegSpace, int offset)
296 {
297     unsigned ret = 0;
298
299     for(int idx = theRegSpace->numFPRs() - 1; idx >= 0; idx--) {
300         registerSlot *reg = theRegSpace->FPRs()[idx];
301
302         //if(reg->liveState == registerSlot::spilled) {
303             int offset_from_sp = offset + (reg->encoding() * FPRSIZE_64);
304             restoreFPRegister(gen, reg->number, offset_from_sp);
305             ret++;
306         //}
307     }
308
309     return ret;
310 }
311
312 unsigned EmitterAARCH64RestoreRegs::restoreSPRegisters(
313         codeGen &gen, registerSpace *theRegSpace, int offset, int force_save)
314 {
315     int ret = 0;
316
317     std::vector<registerSlot *> spRegs;
318     map<registerSlot *, int> regMap;
319
320     registerSlot *regNzcv = (*theRegSpace)[registerSpace::pstate];
321     assert(regNzcv);
322     regMap[regNzcv] = SPR_NZCV;
323     if(force_save || regNzcv->liveState == registerSlot::spilled)
324         spRegs.push_back(regNzcv);
325
326     registerSlot *regFpcr = (*theRegSpace)[registerSpace::fpcr];
327     assert(regFpcr);
328     regMap[regFpcr] = SPR_FPCR;
329     if(force_save || regFpcr->liveState == registerSlot::spilled)
330         spRegs.push_back(regFpcr);
331
332     registerSlot *regFpsr = (*theRegSpace)[registerSpace::fpsr];
333     assert(regFpsr);
334     regMap[regFpsr] = SPR_FPSR;
335     if(force_save || regFpsr->liveState == registerSlot::spilled)
336         spRegs.push_back(regFpsr);
337
338     for(std::vector<registerSlot *>::iterator itr = spRegs.begin(); itr != spRegs.end(); itr++) {
339         registerSlot *cur = *itr;
340         restoreSPR(gen, theRegSpace->getScratchRegister(gen, true), regMap[cur], 4*GPRSIZE_32);
341         ret++;
342     }
343
344     return ret;
345 }
346
347 void EmitterAARCH64RestoreRegs::tearFrame(codeGen &gen) {
348     //Restore frame pointer
349     Register framePointer = gen.rs()->getRegByName("r29");
350     insnCodeGen::restoreRegister(gen, framePointer, 2*GPRSIZE_64);
351
352     //Restore link register
353     Register linkRegister = gen.rs()->getRegByName("r30");
354     insnCodeGen::restoreRegister(gen, linkRegister, 2*GPRSIZE_64);
355 }
356
357
358 /********************************* Private methods *********************************************/
359
360 void EmitterAARCH64RestoreRegs::restoreSPR(codeGen &gen, Register scratchReg, int sprnum, int stkOffset)
361 {
362     insnCodeGen::generateMemAccess(gen, insnCodeGen::Load, scratchReg, REG_SP, stkOffset, 4);
363
364     //TODO move map to common location
365     map<int, int> sysRegCodeMap = map_list_of(SPR_NZCV, 0x5A10)(SPR_FPCR, 0x5A20)(SPR_FPSR, 0x5A21);
366     if (!sysRegCodeMap.count(sprnum))
367         assert(!"Invalid/unknown system register passed to restoreSPR()!");
368
369     instruction insn;
370     insn.clear();
371
372     //Set opcode for MSR (register) instruction
373     INSN_SET(insn, 20, 31, MSROp);
374     //Set source register
375     INSN_SET(insn, 0, 4, scratchReg & 0x1F);
376     //Set bits representing destination system register
377     INSN_SET(insn, 5, 19, sysRegCodeMap[sprnum]);
378     insnCodeGen::generate(gen, insn);
379 }
380
381 void EmitterAARCH64RestoreRegs::restoreFPRegister(codeGen &gen, Register reg, int save_off) {
382     insnCodeGen::generateMemAccessFP(gen, insnCodeGen::Load, reg, REG_SP, save_off, 0, true);
383 }
384
385 /***********************************************************************************************/
386 /***********************************************************************************************/
387
388 /*
389  * Emit code to push down the stack
390  */
391 void pushStack(codeGen &gen)
392 {
393     if (gen.width() == 8)
394         insnCodeGen::generateAddSubImmediate(gen, insnCodeGen::Sub, 0,
395                 TRAMP_FRAME_SIZE_64, REG_SP, REG_SP, true);
396     else
397         assert(0); // 32 bit not implemented
398 }
399
400 void popStack(codeGen &gen)
401 {
402     if (gen.width() == 8)
403         insnCodeGen::generateAddSubImmediate(gen, insnCodeGen::Add, 0,
404                 TRAMP_FRAME_SIZE_64, REG_SP, REG_SP, true);
405     else
406         assert(0); // 32 bit not implemented
407 }
408
409 /*********************************** Base Tramp ***********************************************/
410 bool baseTramp::generateSaves(codeGen &gen, registerSpace *)
411 {
412     regalloc_printf("========== baseTramp::generateSaves\n");
413
414     // Make a stack frame.
415     pushStack(gen);
416
417     EmitterAARCH64SaveRegs saveRegs;
418     unsigned int width = gen.width();
419
420     saveRegs.saveGPRegisters(gen, gen.rs(), TRAMP_GPR_OFFSET(width));
421     // After saving GPR, we move SP to FP to create the instrumentation frame.
422     // Note that Dyninst instrumentation frame has a different structure
423     // compared to stack frame created by the compiler.
424     //
425     // Dyninst instrumentation frame makes sure that FP and SP are the same.
426     // So, during stack walk, the FP retrived from the previous frame is 
427     // the SP of the current instrumentation frame.
428     //
429     // Note: If the implementation of the instrumentation frame layout
430     // needs to be changed, DyninstDynamicStepperImpl::getCallerFrameArch
431     // in stackwalk/src/aarch64-swk.C also likely needs to be changed accordingly
432     insnCodeGen::generateMoveSP(gen, REG_SP, REG_FP, true);
433     gen.markRegDefined(REG_FP);
434
435     bool saveFPRs = BPatch::bpatch->isForceSaveFPROn() ||
436                    (BPatch::bpatch->isSaveFPROn()      &&
437                     gen.rs()->anyLiveFPRsAtEntry()     &&
438                     this->saveFPRs());
439
440     if(saveFPRs) saveRegs.saveFPRegisters(gen, gen.rs(), TRAMP_FPR_OFFSET(width));
441     this->savedFPRs = saveFPRs;
442
443     saveRegs.saveSPRegisters(gen, gen.rs(), TRAMP_SPR_OFFSET(width), false);
444     //gen.rs()->debugPrint();
445
446     return true;
447 }
448
449 bool baseTramp::generateRestores(codeGen &gen, registerSpace *)
450 {
451     EmitterAARCH64RestoreRegs restoreRegs;
452     unsigned int width = gen.width();
453
454     restoreRegs.restoreSPRegisters(gen, gen.rs(), TRAMP_SPR_OFFSET(width), false);
455
456     if(this->savedFPRs)
457         restoreRegs.restoreFPRegisters(gen, gen.rs(), TRAMP_FPR_OFFSET(width));
458
459     restoreRegs.restoreGPRegisters(gen, gen.rs(), TRAMP_GPR_OFFSET(width));
460
461     // Tear down the stack frame.
462     popStack(gen);
463
464     return true;
465 }
466
467 /***********************************************************************************************/
468 /***********************************************************************************************/
469
470 //TODO: 32-/64-bit regs?
471 void emitImm(opCode op, Register src1, RegValue src2imm, Register dest, 
472         codeGen &gen, bool /*noCost*/, registerSpace * /* rs */, bool s)
473 {
474     switch(op) {
475         case plusOp:
476         case minusOp:
477             {
478                 Register rm = insnCodeGen::moveValueToReg(gen, src2imm);
479                 insnCodeGen::generateAddSubShifted(gen,
480                         op == plusOp ? insnCodeGen::Add : insnCodeGen::Sub,
481                         0, 0, rm, src1, dest, true);
482             }
483             break;
484         case timesOp:
485             {
486                 Register rm = insnCodeGen::moveValueToReg(gen, src2imm);
487                 insnCodeGen::generateMul(gen, rm, src1, dest, true);
488             }
489             break;
490         case divOp:
491             {
492                 Register rm = insnCodeGen::moveValueToReg(gen, src2imm);
493                 insnCodeGen::generateDiv(gen, rm, src1, dest, true, s);
494             }
495             break;
496         case xorOp:
497             {
498                 Register rm = insnCodeGen::moveValueToReg(gen, src2imm);
499                 insnCodeGen::generateBitwiseOpShifted(gen, insnCodeGen::Eor, 0, rm, 0, src1, dest, true);
500             }
501             break;
502         case orOp:
503             {
504                 Register rm = insnCodeGen::moveValueToReg(gen, src2imm);
505                 insnCodeGen::generateBitwiseOpShifted(gen, insnCodeGen::Or, 0, rm, 0, src1, dest, true);
506             }
507             break;
508         case andOp:
509             {
510                 Register rm = insnCodeGen::moveValueToReg(gen, src2imm);
511                 insnCodeGen::generateBitwiseOpShifted(gen, insnCodeGen::And, 0, rm, 0, src1, dest, true);
512             }
513             break;
514         case eqOp:
515             {
516                 Register scratch = gen.rs()->getScratchRegister(gen);
517                 emitVload(loadConstOp, src2imm, NULL, scratch, gen, true);
518                 emitV(op, src1, scratch, dest, gen, true);
519             }
520             break;
521         case neOp:
522         case lessOp:
523         case leOp:
524         case greaterOp:
525         case geOp:
526             // note that eqOp could be grouped here too.
527             // There's two ways to implement this.
528             gen.codeEmitter()->emitRelOpImm(op, dest, src1, src2imm, gen, s);
529             return;
530         default:
531             assert(0); // not implemented or not valid
532             break;
533     }
534 }
535
536 void cleanUpAndExit(int status);
537
538 /* Recursive function that goes to where our instrumentation is calling
539 to figure out what registers are clobbered there, and in any function
540 that it calls, to a certain depth ... at which point we clobber everything
541
542 Update-12/06, njr, since we're going to a cached system we are just going to
543 look at the first level and not do recursive, since we would have to also
544 store and reexamine every call out instead of doing it on the fly like before*/
545 bool EmitterAARCH64::clobberAllFuncCall(registerSpace *rs,
546                                         func_instance *callee) {
547     if(!callee)
548         return true;
549
550     stats_codegen.startTimer(CODEGEN_LIVENESS_TIMER);
551
552     if(callee->ifunc()->isLeafFunc()) {
553         std::set<Register> *gpRegs = callee->ifunc()->usedGPRs();
554         for(std::set<Register>::iterator itr = gpRegs->begin(); itr != gpRegs->end(); itr++)
555             rs->GPRs()[*itr]->beenUsed = true;
556
557         std::set<Register> *fpRegs = callee->ifunc()->usedFPRs();
558         for(std::set<Register>::iterator itr = fpRegs->begin(); itr != fpRegs->end(); itr++)
559             rs->FPRs()[*itr]->beenUsed = true;
560     } else {
561         for(int idx = 0; idx < rs->numGPRs(); idx++)
562             rs->GPRs()[idx]->beenUsed = true;
563         for(int idx = 0; idx < rs->numFPRs(); idx++)
564             rs->FPRs()[idx]->beenUsed = true;
565     }
566
567     stats_codegen.stopTimer(CODEGEN_LIVENESS_TIMER);
568
569     return false;
570 }
571
572 Register emitFuncCall(opCode, codeGen &, std::vector <AstNodePtr> &, bool, Address) {
573     assert(0);
574     return 0;
575 }
576
577 Register emitFuncCall(opCode op,
578                       codeGen &gen,
579                       std::vector <AstNodePtr> &operands, bool noCost,
580                       func_instance *callee) {
581     return gen.emitter()->emitCall(op, gen, operands, noCost, callee);
582 }
583
584 Register EmitterAARCH64::emitCallReplacement(opCode ocode,
585                                              codeGen &gen,
586                                              bool /* noCost */,
587                                              func_instance *callee) {
588     assert(0); //Not implemented
589     return 0;
590 }
591
592 // There are four "axes" going on here:
593 // 32 bit vs 64 bit
594 // Instrumentation vs function call replacement
595 // Static vs. dynamic
596
597 Register EmitterAARCH64::emitCall(opCode op,
598                                   codeGen &gen,
599                                   const std::vector<AstNodePtr> &operands,
600                                   bool noCost,
601                                   func_instance *callee) 
602 {
603     //#sasha This function implementation is experimental.
604
605     if (op != callOp) {
606         cerr << "ERROR: emitCall with op == " << op << endl;
607     }
608     assert(op == callOp);
609
610     std::vector<Register> srcs;
611     std::vector<Register> saves;
612
613     //  Sanity check for NULL address arg
614     if (!callee) 
615     {
616         char msg[256];
617         sprintf(msg, "%s[%d]:  internal error:  emitFuncCall called w/out"
618                 "callee argument", __FILE__, __LINE__);
619         showErrorCallback(80, msg);
620         assert(0);
621     }
622
623     vector<int> savedRegs;
624
625     // save r0-r7
626     for(size_t id = 0; id < gen.rs()->numGPRs(); id++)
627     {
628         registerSlot *reg = gen.rs()->GPRs()[id];
629
630         // We must save if:
631         // refCount > 0 (and not a source register)
632         // keptValue == true (keep over the call)
633         // liveState == live (technically, only if not saved by the callee)
634
635         if ((reg->refCount > 0) || reg->keptValue || (reg->liveState == registerSlot::live))
636         {
637             insnCodeGen::saveRegister(gen, registerSpace::r0 + id,
638                     -2*GPRSIZE_64, insnCodeGen::Post);
639             savedRegs.push_back(reg->number);
640         }
641     }
642
643     // Passing operands to registers
644     for(size_t id = 0; id < operands.size(); id++)
645     {
646         Register reg = REG_NULL;
647         if (gen.rs()->allocateSpecificRegister(gen, registerSpace::r0 + id, true))
648             reg = registerSpace::r0 + id;
649
650         Address unnecessary = ADDR_NULL;
651         if (!operands[id]->generateCode_phase2(gen, false, unnecessary, reg))
652             assert(0);
653         assert(reg!=REG_NULL);
654     }
655
656     assert(gen.rs());
657
658     //Address of function to call in scratch register
659     Register scratch = gen.rs()->getScratchRegister(gen);
660     assert(scratch != REG_NULL && "cannot get a scratch register");
661     gen.markRegDefined(scratch);
662     if (gen.addrSpace()->edit() != NULL && gen.func()->obj() != callee->obj()) {
663         // gen.as.edit() checks if we are in rewriter mode
664         Address dest = getInterModuleFuncAddr(callee, gen);
665         insnCodeGen::loadImmIntoReg<Address>(gen, scratch, dest);
666
667         insnCodeGen::generateMemAccess(gen, insnCodeGen::Load, scratch, scratch, 0, 8, insnCodeGen::Offset);
668     } else {
669         insnCodeGen::loadImmIntoReg<Address>(gen, scratch, callee->addr());
670     }
671
672     instruction branchInsn;
673     branchInsn.clear();
674
675     //Set bits which are 0 for both BR and BLR
676     INSN_SET(branchInsn, 0, 4, 0);
677     INSN_SET(branchInsn, 10, 15, 0);
678
679     //Set register
680     INSN_SET(branchInsn, 5, 9, scratch);
681
682     //Set other bits. Basically, these are the opcode bits.
683     //The only difference between BR and BLR is that bit 21 is 1 for BLR.
684     INSN_SET(branchInsn, 16, 31, BRegOp);
685     INSN_SET(branchInsn, 21, 21, 1);
686     insnCodeGen::generate(gen, branchInsn);
687
688     /*
689      * Restoring registers
690      */
691
692     // r7-r0
693     for (signed int ui = savedRegs.size()-1; ui >= 0; ui--) {
694         insnCodeGen::restoreRegister(gen, registerSpace::r0 + savedRegs[ui],
695                 2*GPRSIZE_64, insnCodeGen::Post);
696     }
697
698     return 0;
699 }
700
701
702 codeBufIndex_t emitA(opCode op, Register src1, Register src2, long dest,
703         codeGen &gen, RegControl rc, bool noCost)
704 {
705     codeBufIndex_t retval = 0;
706
707     switch (op) {
708         case ifOp: 
709             {
710                 // if src1 == 0 jump to dest
711                 // src1 is a temporary
712                 // dest is a target address
713                 retval = gen.codeEmitter()->emitIf(src1, dest, rc, gen);
714                 break;
715             }
716         case branchOp:
717             {
718                 insnCodeGen::generateBranch(gen, dest);
719                 retval = gen.getIndex();
720                 break;
721             }
722         default:
723             assert(0);        // op not implemented or not expected for this emit!
724     }
725
726     return retval;
727 }
728
729 Register emitR(opCode op, Register src1, Register src2, Register dest,
730                codeGen &gen, bool /*noCost*/,
731                const instPoint * location, bool /*for_MT*/)
732 {
733     registerSlot *regSlot = NULL;
734     unsigned addrWidth = gen.width();
735
736     switch(op){
737         case getRetValOp:
738             regSlot = (*(gen.rs()))[registerSpace::r0];
739             break;
740         case getParamOp:
741             // src1 is the number of the argument
742             // dest is a register where we can store the value
743             //gen.codeEmitter()->emitGetParam(dest, src1, location->type(), op,
744             //        false, gen);
745
746             if(src1 <= 7) {
747                 // src1 is 0..7 - it's a parameter order number, not a register
748                 regSlot = (*(gen.rs()))[registerSpace::r0 + src1];
749                 break;
750
751             } else {
752                 int stkOffset = TRAMP_FRAME_SIZE_64 + (src1 - 8) * sizeof(long);
753                 // printf("TRAMP_FRAME_SIZE_64: %d\n", TRAMP_FRAME_SIZE_64);
754                 // printf("stdOffset = TRAMP_xxx_64 + (argc - 8) * 8 = { %d }\n", stkOffset);
755                 // TODO: PARAM_OFFSET(addrWidth) is currently not used
756                 // should delete that macro if it's useless
757
758                 if (src2 != REG_NULL) insnCodeGen::saveRegister(gen, src2, stkOffset);
759                 insnCodeGen::restoreRegister(gen, dest, stkOffset);
760
761                 return dest;
762             }
763             break;
764         default:
765             assert(0);
766     }
767
768     assert(regSlot);
769     Register reg = regSlot->number;
770
771     switch(regSlot->liveState) {
772         case registerSlot::spilled:
773             {
774                 int offset = TRAMP_GPR_OFFSET(addrWidth);
775                 // its on the stack so load it.
776                 //if (src2 != REG_NULL) saveRegister(gen, src2, reg, offset);
777                 insnCodeGen::restoreRegister(gen, dest, offset + (reg * gen.width()));
778                 return(dest);
779             }
780         case registerSlot::live:
781             {
782                 // its still in a register so return the register it is in.
783                 cerr << "emitR state:" << reg << " live" << endl;
784                 assert(0);
785                 return(reg);
786             }
787         case registerSlot::dead:
788             {
789                 cerr << "emitR state" << reg << ": dead" << endl;
790                 // Uhhh... wha?
791                 assert(0);
792             }
793     }
794     return reg;
795 }
796
797 void emitJmpMC(int /*condition*/, int /*offset*/, codeGen &) {
798     assert(0); //Not implemented
799     // Not needed for memory instrumentation, otherwise TBD
800 }
801
802
803 // VG(03/15/02): Restore mutatee value of GPR reg to dest GPR
804 static inline void restoreGPRtoGPR(codeGen &gen,
805                                    Register reg, Register dest) {
806     int frame_size, gpr_size, gpr_off;
807
808         frame_size = TRAMP_FRAME_SIZE_64;
809     gpr_size   = GPRSIZE_64;
810     gpr_off    = TRAMP_GPR_OFFSET_64;   
811         
812         //Stack Point Register
813         if(reg == 31) {
814             insnCodeGen::generateAddSubImmediate(gen, insnCodeGen::Add, 0, frame_size, REG_SP, dest, true);     
815         }
816         else {
817                 insnCodeGen::restoreRegister(gen, dest, gpr_off + reg*gpr_size);
818         }
819         
820         return;
821 }
822
823 // VG(03/15/02): Restore mutatee value of XER to dest GPR
824 static inline void restoreXERtoGPR(codeGen &gen, Register dest) {
825     assert(0); //Not implemented
826 }
827
828 // VG(03/15/02): Move bits 25:31 of GPR reg to GPR dest
829 static inline void moveGPR2531toGPR(codeGen &gen,
830                                     Register reg, Register dest) {
831     assert(0); //Not implemented
832 }
833
834 // VG(11/16/01): Emit code to add the original value of a register to
835 // another. The original value may need to be restored from stack...
836 // VG(03/15/02): Made functionality more obvious by adding the above functions
837 static inline void emitAddOriginal(Register src, Register acc,
838                                    codeGen &gen, bool noCost) {
839     emitV(plusOp, src, acc, acc, gen, noCost, 0);
840 }
841
842
843 //Not correctly implemented
844 void MovePCToReg(Register dest, codeGen &gen) {
845     instruction insn;
846     insn.clear();
847
848     INSN_SET(insn, 28, 28, 1);
849     INSN_SET(insn, 0, 4, dest);
850
851     insnCodeGen::generate(gen, insn);
852     Address ret = gen.currAddr();
853     return;
854 }
855
856 // Yuhan(02/04/19): Load in destination the effective address given
857 // by the address descriptor. Used for memory access stuff.
858 void emitASload(const BPatch_addrSpec_NP *as, Register dest, int stackShift,
859                 codeGen &gen,
860                 bool noCost) {
861
862     // Haven't implemented non-zero shifts yet
863     assert(stackShift == 0);
864     long int imm = as->getImm();
865     int ra  = as->getReg(0);
866     int rb  = as->getReg(1);
867     int sc  = as->getScale();
868     gen.markRegDefined(dest);
869     if(ra > -1) {
870         if(ra == 32) {
871             // Special case where the actual address is store in imm.
872             // Need to change this for rewriting PIE or shared libraries
873             insnCodeGen::loadImmIntoReg<long int>(gen, dest, imm);
874             return;
875         }
876         else {
877             restoreGPRtoGPR(gen, ra, dest);
878         }
879     } else {
880         insnCodeGen::loadImmIntoReg<long int>(gen, dest, 0);
881     }
882     if(rb > -1) {
883         std::vector<Register> exclude;
884         exclude.push_back(dest);
885         Register scratch = gen.rs()->getScratchRegister(gen, exclude);
886         assert(scratch != REG_NULL && "cannot get a scratch register");
887         gen.markRegDefined(scratch);
888         restoreGPRtoGPR(gen, rb, scratch);
889         // call adds, save 2^scale * rb to dest
890         insnCodeGen::generateAddSubShifted(gen, insnCodeGen::Add, 0, sc, scratch, dest, dest, true);
891     }
892         
893     // emit code to load the immediate (constant offset) into dest; this
894     // writes at gen+base and updates base, we must update insn..
895     if (imm) 
896         insnCodeGen::generateAddSubImmediate(gen, insnCodeGen::Add, 0, imm, dest, dest, true);  
897 }
898
899 void emitCSload(const BPatch_addrSpec_NP *as, Register dest, codeGen &gen,
900                 bool noCost) {
901     assert(0); //Not implemented
902 }
903
904 void emitVload(opCode op, Address src1, Register src2, Register dest,
905                codeGen &gen, bool /*noCost*/,
906                registerSpace * /*rs*/, int size,
907                const instPoint * /* location */, AddressSpace *proc)
908 {
909     switch(op)
910     {
911         case loadConstOp:
912             // dest is a temporary
913             // src1 is an immediate value
914             // dest = src1:imm32
915             gen.codeEmitter()->emitLoadConst(dest, src1, gen);
916             break;
917         case loadOp:
918             // dest is a temporary
919             // src1 is the address of the operand
920             // dest = [src1]
921             gen.codeEmitter()->emitLoad(dest, src1, size, gen);
922             break;
923         case loadRegRelativeAddr:
924             // (readReg(src2) + src1)
925             // dest is a temporary
926             // src2 is the register
927             // src1 is the offset from the address in src2
928             gen.codeEmitter()->emitLoadOrigRegRelative(dest, src1, src2, gen, false);
929             break;
930         case loadRegRelativeOp:
931             // *(readReg(src2) + src1)
932             // dest is a temporary
933             // src2 is the register
934             // src1 is the offset from the address in src2
935             gen.codeEmitter()->emitLoadOrigRegRelative(dest, src1, src2, gen, true);
936             break;
937         default:
938             assert(0); //Not implemented
939             break;
940     }
941 }
942
943 void emitVstore(opCode op, Register src1, Register /*src2*/, Address dest,
944         codeGen &gen, bool noCost,
945         registerSpace * /* rs */, int size,
946         const instPoint * /* location */, AddressSpace *proc)
947 {
948     if (op ==  storeOp) {
949         // [dest] = src1
950         // dest has the address where src1 is to be stored
951         // src1 is a temporary
952         // src2 is a "scratch" register, we don't need it in this architecture
953         gen.codeEmitter()->emitStore(dest, src1, size, gen);
954     }else{
955         assert(0); //Not implemented
956     }
957     return;
958 }
959
960 void emitV(opCode op, Register src1, Register src2, Register dest,
961         codeGen &gen, bool /*noCost*/,
962            registerSpace * /*rs*/, int size,
963            const instPoint * /* location */, AddressSpace *proc, bool s) 
964 {
965     switch(op){
966         case plusOp:
967         case minusOp:
968         case timesOp:
969         case orOp:
970         case andOp:
971         case xorOp:
972             gen.codeEmitter()->emitOp(op, dest, src1, src2, gen);
973             break;
974         case divOp:
975             insnCodeGen::generateDiv(gen, src2, src1, dest, true, s);
976             break;
977         case lessOp:
978         case leOp:
979         case greaterOp:
980         case geOp:
981         case eqOp:
982         case neOp:
983             gen.codeEmitter()->emitRelOp(op, dest, src1, src2, gen, s);
984             break;
985         case loadIndirOp:
986             size = !size ? proc->getAddressWidth() : size;
987             // same as loadOp, but the value to load is already in a register
988             gen.codeEmitter()->emitLoadIndir(dest, src1, size, gen);
989             break;
990         case storeIndirOp:
991             size = !size ? proc->getAddressWidth() : size;
992             gen.codeEmitter()->emitStoreIndir(dest, src1, size, gen);
993             break;
994         default:
995             //std::cout << "operation not implemented= " << op << endl;
996             assert(0); // Not implemented
997             break;
998     }
999     return;
1000 }
1001
1002 //
1003 // I don't know how to compute cycles for AARCH64 instructions due to
1004 //   multiple functional units.  However, we can compute the number of
1005 //   instructions and hope that is fairly close. - jkh 1/30/96
1006 //
1007 int getInsnCost(opCode op) {
1008     assert(0); //Not implemented
1009     return NULL;
1010 }
1011
1012 #if 0
1013 // What does this do???
1014 void registerSpace::saveClobberInfo(const instPoint *location)
1015 {
1016   registerSlot *regSlot = NULL;
1017   registerSlot *regFPSlot = NULL;
1018   if (location == NULL)
1019     return;
1020   if (location->actualGPRLiveSet_ != NULL && location->actualFPRLiveSet_ != NULL)
1021     {
1022
1023       // REG guard registers, if live, must be saved
1024       if (location->actualGPRLiveSet_[ REG_GUARD_ADDR ] == LIVE_REG)
1025     location->actualGPRLiveSet_[ REG_GUARD_ADDR ] = LIVE_CLOBBERED_REG;
1026
1027       if (location->actualGPRLiveSet_[ REG_GUARD_OFFSET ] == LIVE_REG)
1028     location->actualGPRLiveSet_[ REG_GUARD_OFFSET ] = LIVE_CLOBBERED_REG;
1029
1030       // GPR and FPR scratch registers, if live, must be saved
1031       if (location->actualGPRLiveSet_[ REG_SCRATCH ] == LIVE_REG)
1032     location->actualGPRLiveSet_[ REG_SCRATCH ] = LIVE_CLOBBERED_REG;
1033
1034       if (location->actualFPRLiveSet_[ REG_SCRATCH ] == LIVE_REG)
1035     location->actualFPRLiveSet_[ REG_SCRATCH ] = LIVE_CLOBBERED_REG;
1036
1037       // Return func call register, since we make a call because
1038       // of multithreading (regardless if it's threaded) from BT
1039       // we must save return register
1040       if (location->actualGPRLiveSet_[ 3 ] == LIVE_REG)
1041     location->actualGPRLiveSet_[ 3 ] = LIVE_CLOBBERED_REG;
1042
1043
1044       for (u_int i = 0; i < getRegisterCount(); i++)
1045     {
1046       regSlot = getRegSlot(i);
1047
1048       if (  location->actualGPRLiveSet_[ (int) registers[i].number ] == LIVE_REG )
1049         {
1050           if (!registers[i].beenClobbered)
1051         location->actualGPRLiveSet_[ (int) registers[i].number ] = LIVE_UNCLOBBERED_REG;
1052           else
1053         location->actualGPRLiveSet_[ (int) registers[i].number ] = LIVE_CLOBBERED_REG;
1054         }
1055
1056
1057       if (  location->actualGPRLiveSet_[ (int) registers[i].number ] == LIVE_UNCLOBBERED_REG )
1058         {
1059           if (registers[i].beenClobbered)
1060         location->actualGPRLiveSet_[ (int) registers[i].number ] = LIVE_CLOBBERED_REG;
1061         }
1062     }
1063
1064       for (u_int i = 0; i < getFPRegisterCount(); i++)
1065     {
1066       regFPSlot = getFPRegSlot(i);
1067
1068       if (  location->actualFPRLiveSet_[ (int) fpRegisters[i].number ] == LIVE_REG )
1069         {
1070           if (!fpRegisters[i].beenClobbered)
1071         location->actualFPRLiveSet_[ (int) fpRegisters[i].number ] = LIVE_UNCLOBBERED_REG;
1072           else
1073         location->actualFPRLiveSet_[ (int) fpRegisters[i].number ] = LIVE_CLOBBERED_REG;
1074         }
1075
1076       if (  location->actualFPRLiveSet_[ (int) fpRegisters[i].number ] == LIVE_UNCLOBBERED_REG )
1077         {
1078           if (fpRegisters[i].beenClobbered)
1079         location->actualFPRLiveSet_[ (int) fpRegisters[i].number ] = LIVE_CLOBBERED_REG;
1080         }
1081     }
1082     }
1083 }
1084 #endif
1085
1086 // This is used for checking wether immediate value should be encoded
1087 // into a instruction. In fact, only being used for loading constant
1088 // value into a register, and in ARMv8 there are 16 bits for immediate
1089 // values in the instruction MOV.
1090 // value here is never a negative value since constant values are saved
1091 // as void* in the AST operand.
1092 bool doNotOverflow(int64_t value)
1093 {
1094     if ((value >= 0) && (value <= 0xFFFF)) return true;
1095     else return false;
1096 }
1097
1098
1099 #if !defined(os_vxworks)
1100
1101 // hasBeenBound: returns true if the runtime linker has bound the
1102 // function symbol corresponding to the relocation entry in at the address
1103 // specified by entry and base_addr.  If it has been bound, then the callee
1104 // function is returned in "target_pdf", else it returns false.
1105 bool PCProcess::hasBeenBound(const SymtabAPI::relocationEntry &entry,
1106                              func_instance *&target_pdf, Address base_addr)
1107 {
1108         if (isTerminated()) return false;
1109
1110         // if the relocationEntry has not been bound yet, then the value
1111         // at rel_addr is the address of the instruction immediately following
1112         // the first instruction in the PLT entry (which is at the target_addr)
1113         // The PLT entries are never modified, instead they use an indirrect
1114         // jump to an address stored in the _GLOBAL_OFFSET_TABLE_.  When the
1115         // function symbol is bound by the runtime linker, it changes the address
1116         // in the _GLOBAL_OFFSET_TABLE_ corresponding to the PLT entry
1117
1118         Address got_entry = entry.rel_addr() + base_addr;
1119         Address bound_addr = 0;
1120         if (!readDataSpace((const void*)got_entry, sizeof(Address),
1121                                 &bound_addr, true)){
1122                 sprintf(errorLine, "read error in PCProcess::hasBeenBound addr 0x%x, pid=%d\n (readDataSpace returns 0)",(unsigned)got_entry,getPid());
1123                 logLine(errorLine);
1124                 //print_read_error_info(entry, target_pdf, base_addr);
1125                 fprintf(stderr, "%s[%d]: %s\n", FILE__, __LINE__, errorLine);
1126                 return false;
1127         }
1128
1129    //fprintf(stderr, "%s[%d]:  hasBeenBound:  %p ?= %p ?\n", FILE__, __LINE__, bound_addr, entry.target_addr() + 6 + base_addr);
1130         if ( !( bound_addr == (entry.target_addr()+6+base_addr)) ) {
1131           // the callee function has been bound by the runtime linker
1132           // find the function and return it
1133           target_pdf = findFuncByEntry(bound_addr);
1134           if(!target_pdf){
1135             return false;
1136           }
1137           return true;
1138         }
1139         return false;
1140 }
1141
1142 #endif
1143
1144 bool PCProcess::bindPLTEntry(const SymtabAPI::relocationEntry &, Address,
1145                              func_instance *, Address) {
1146     assert(0); //Not implemented
1147     assert(0 && "TODO!");
1148     return false;
1149 }
1150
1151 void emitLoadPreviousStackFrameRegister(Address register_num,
1152                                         Register dest,
1153                                         codeGen &gen,
1154                                         int /*size*/,
1155                                         bool noCost)
1156 {
1157     gen.codeEmitter()->emitLoadOrigRegister(register_num, dest, gen);
1158 }
1159
1160 void emitStorePreviousStackFrameRegister(Address,
1161                                          Register,
1162                                          codeGen &,
1163                                          int,
1164                                          bool) {
1165     assert(0);
1166 }
1167
1168 // First AST node: target of the call
1169 // Second AST node: source of the call
1170 // This can handle indirect control transfers as well
1171 bool AddressSpace::getDynamicCallSiteArgs(InstructionAPI::Instruction i,
1172                                           Address addr,
1173                                           pdvector<AstNodePtr> &args)
1174 {
1175     using namespace Dyninst::InstructionAPI;
1176     Register branch_target = registerSpace::ignored;
1177
1178     for(Instruction::cftConstIter curCFT = i.cft_begin();
1179             curCFT != i.cft_end(); ++curCFT)
1180     {
1181         auto target_reg = dynamic_cast<RegisterAST *>(curCFT->target.get());
1182         if(!target_reg) return false;
1183         branch_target = target_reg->getID() & 0x1f;
1184         break;
1185     }
1186
1187     if(branch_target == registerSpace::ignored) return false;
1188
1189     //jumping to Xn (BLR Xn)
1190     args.push_back(AstNode::operandNode(AstNode::origRegister,(void *) branch_target));
1191     args.push_back(AstNode::operandNode(AstNode::Constant, (void *) addr));
1192
1193     //inst_printf("%s[%d]:  Inserting dynamic call site instrumentation for %s\n",
1194     //        FILE__, __LINE__, cft->format(insn.getArch()).c_str());
1195     return true;
1196 }
1197
1198 bool writeFunctionPtr(AddressSpace *p, Address addr, func_instance *f) {
1199     Address val_to_write = f->addr();
1200     return p->writeDataSpace((void *) addr, sizeof(Address), &val_to_write);
1201     return false;
1202 }
1203
1204 Emitter *AddressSpace::getEmitter() {
1205     static EmitterAARCH64Stat emitter64Stat;
1206     static EmitterAARCH64Dyn emitter64Dyn;
1207
1208     if (proc())
1209         return &emitter64Dyn;
1210
1211     return &emitter64Stat;
1212 }
1213
1214 #define GET_IP      0x429f0005
1215 #define MFLR_30     0x7fc802a6
1216 #define ADDIS_30_30 0x3fde0000
1217 #define ADDI_30_30  0x3bde0000
1218 #define LWZ_11_30   0x817e0000
1219 #define ADDIS_11_30 0x3d7e0000
1220
1221 /*
1222  * If the target stub_addr is a glink stub, try to determine the actual
1223  * function called (through the GOT) and fill in that information.
1224  *
1225  * The function at stub_addr may not have been created when this method
1226  * is called.
1227  *
1228  * XXX Is this a candidate to move into general parsing code, or is
1229  *     this properly a Dyninst-only technique?
1230  */
1231
1232 /*
1233 bool image::updatePltFunc(parse_func *caller_func, Address stub_addr)
1234 {
1235         assert(0); //Not implemented
1236     return true;
1237 }
1238 */
1239
1240 bool EmitterAARCH64::emitCallRelative(Register dest, Address offset, Register base, codeGen &gen) {
1241     assert(0); //Not implemented
1242     return true;
1243 }
1244
1245 bool EmitterAARCH64::emitLoadRelative(Register dest, Address offset, Register base, int size, codeGen &gen) {
1246     insnCodeGen::generateMemAccess(gen, insnCodeGen::Load, dest,
1247             base, offset, size, insnCodeGen::Pre);
1248
1249     gen.markRegDefined(dest);
1250     return true;
1251 }
1252
1253
1254 void EmitterAARCH64::emitStoreRelative(Register source, Address offset, Register base, int size, codeGen &gen) {
1255     insnCodeGen::generateMemAccess(gen, insnCodeGen::Store, source,
1256             base, offset, size, insnCodeGen::Pre);
1257 }
1258
1259 bool EmitterAARCH64::emitMoveRegToReg(registerSlot *src,
1260                                       registerSlot *dest,
1261                                       codeGen &gen) {
1262     assert(0); //Not implemented
1263     return true;
1264 }
1265
1266 /*
1267 bool EmitterAARCH6432Stat::emitPIC(codeGen& gen, Address origAddr, Address relocAddr) {
1268
1269       Register scratchPCReg = gen.rs()->getScratchRegister(gen, true);
1270       std::vector<Register> excludeReg;
1271       excludeReg.push_back(scratchPCReg);
1272       Register scratchReg = gen.rs()->getScratchRegister(gen, excludeReg, true);
1273       bool newStackFrame = false;
1274       int stack_size = 0;
1275       int gpr_off, fpr_off, ctr_off;
1276       //fprintf(stderr, " emitPIC origAddr 0x%lx reloc 0x%lx Registers PC %d scratch %d \n", origAddr, relocAddr, scratchPCReg, scratchReg);
1277       if ((scratchPCReg == REG_NULL) || (scratchReg == REG_NULL)) {
1278                 //fprintf(stderr, " Creating new stack frame for 0x%lx to 0x%lx \n", origAddr, relocAddr);
1279
1280                 newStackFrame = true;
1281                 //create new stack frame
1282                 gpr_off = TRAMP_GPR_OFFSET_32;
1283                 fpr_off = TRAMP_FPR_OFFSET_32;
1284                 ctr_off = STK_CTR_32;
1285
1286                 // Make a stack frame.
1287                 pushStack(gen);
1288
1289                 // Save GPRs
1290               stack_size = saveGPRegisters(gen, gen.rs(), gpr_off, 2);
1291
1292               scratchPCReg = gen.rs()->getScratchRegister(gen, true);
1293               assert(scratchPCReg != REG_NULL);
1294               excludeReg.clear();
1295               excludeReg.push_back(scratchPCReg);
1296               scratchReg = gen.rs()->getScratchRegister(gen, excludeReg, true);
1297               assert(scratchReg != REG_NULL);
1298               // relocaAddr has moved since we added instructions to setup a new stack frame
1299               relocAddr = relocAddr + ((stack_size + 1)*(gen.width()));
1300               //fprintf(stderr, " emitPIC origAddr 0x%lx reloc 0x%lx stack size %d Registers PC %d scratch %d \n", origAddr, relocAddr, stack_size, scratchPCReg, scratchReg);
1301
1302         }
1303         emitMovePCToReg(scratchPCReg, gen);
1304         Address varOffset = origAddr - relocAddr;
1305         emitCallRelative(scratchReg, varOffset, scratchPCReg, gen);
1306         insnCodeGen::generateMoveToLR(gen, scratchReg);
1307         if(newStackFrame) {
1308               // GPRs
1309               restoreGPRegisters(gen, gen.rs(), gpr_off);
1310               popStack(gen);
1311         }
1312
1313       return 0;
1314 }
1315
1316 bool EmitterAARCH64Stat::emitPIC(codeGen& gen, Address origAddr, Address relocAddr) {
1317         assert(0);
1318         return false;
1319 }
1320 bool EmitterAARCH64Dyn::emitPIC(codeGen &gen, Address origAddr, Address relocAddr) {
1321
1322         Address origRet = origAddr + 4;
1323         Register scratch = gen.rs()->getScratchRegister(gen, true);
1324         assert(scratch != REG_NULL);
1325         instruction::loadImmIntoReg(gen, scratch, origRet);
1326         insnCodeGen::generateMoveToLR(gen, scratch);
1327         return true;
1328
1329 }
1330 */
1331
1332 bool EmitterAARCH64Stat::emitPLTCommon(func_instance *callee, bool call, codeGen &gen) {
1333     assert(0); //Not implemented
1334     return true;
1335 }
1336
1337 #if 0
1338 bool EmitterAARCH64Stat::emitPLTCommon(func_instance *callee, bool call, codeGen &gen) {
1339   // In PPC64 Linux, function descriptors are used in place of direct
1340   // function pointers.  The descriptors have the following layout:
1341   //
1342   // Function Descriptor --> + 0: <Function Text Address>
1343   //                         + 8: <TOC Pointer Value>
1344   //                         +16: <Environment Pointer [Optional]>
1345   //
1346   // Additionally, this should be able to stomp on the link register (LR)
1347   // and TOC register (r2), as they were saved by Emitter::emitCall() if
1348   // necessary.
1349   //
1350   // So here's a brief sketch of the code this function generates:
1351   //
1352   //   Set up new branch target in LR from function descriptor
1353   //   Set up new TOC in R2 from function descriptor + 8
1354   //   Call
1355   bool isStaticBinary = false;
1356
1357   if(gen.addrSpace()->edit()->getMappedObject()->parse_img()->getObject()->isStaticBinary()) {
1358     isStaticBinary = true;
1359   }
1360
1361   const unsigned TOCreg = 2;
1362   const unsigned wordsize = gen.width();
1363   assert(wordsize == 8);
1364   Address dest = getInterModuleFuncAddr(callee, gen);
1365   Address caller_toc = 0;
1366   Address toc_anchor = gen.addrSpace()->getTOCoffsetInfo(callee);
1367   // Instead of saving the TOC (if we can't), just reset it afterwards.
1368   if (gen.func()) {
1369     caller_toc = gen.addrSpace()->getTOCoffsetInfo(gen.func());
1370   }
1371   else if (gen.point()) {
1372     caller_toc = gen.addrSpace()->getTOCoffsetInfo(gen.point()->func());
1373   }
1374   else {
1375     // Don't need it, and this might be an iRPC
1376   }
1377
1378   if(isStaticBinary)
1379     caller_toc = 0;
1380
1381   //Offset destOff = dest - gen.currAddr();
1382   Offset destOff = dest - caller_toc;
1383
1384   //    insnCodeGen::loadPartialImmIntoReg(gen, TOCreg, destOff);
1385   // Broken to see if any of this generates intellible code.
1386
1387   Register scratchReg = 3; // = gen.rs()->getScratchRegister(gen, true);
1388   int stackSize = 0;
1389   if (scratchReg == REG_NULL) {
1390     std::vector<Register> freeReg;
1391     std::vector<Register> excludeReg;
1392     stackSize = insnCodeGen::createStackFrame(gen, 1, freeReg, excludeReg);
1393     assert (stackSize == 1);
1394     scratchReg = freeReg[0];
1395   }
1396   insnCodeGen::loadImmIntoReg<Offset?(gen, scratchReg, destOff);
1397
1398   if(!isStaticBinary) {
1399     insnCodeGen::generateLoadReg64(gen, scratchReg, scratchReg, TOCreg);
1400
1401     insnCodeGen::generateMemAccess64(gen, LDop, LDxop,
1402                      TOCreg, scratchReg, 8);
1403   }
1404   insnCodeGen::generateMemAccess64(gen, LDop, LDxop,
1405                    scratchReg, scratchReg, 0);
1406
1407   insnCodeGen::generateMoveToCR(gen, scratchReg);
1408
1409   if (stackSize > 0)
1410     insnCodeGen::removeStackFrame(gen);
1411
1412
1413   instruction branch_insn(call ? BCTRLraw : BCTRraw);
1414   insnCodeGen::generate(gen, branch_insn);
1415
1416   return true;
1417 }
1418 #endif
1419
1420 bool EmitterAARCH64Dyn::emitTOCCommon(block_instance *block, bool call, codeGen &gen) {
1421     assert(0); //Not implemented
1422     return true;
1423 }
1424
1425 // TODO 32/64-bit?
1426 bool EmitterAARCH64Stat::emitPLTCall(func_instance *callee, codeGen &gen) {
1427     /*
1428     Address dest = getInterModuleFuncAddr(callee, gen);
1429     //Register scr = gen.rs()->getScratchRegister(gen);
1430     //Register lr = gen.rs()->getScratchRegister(gen);
1431     //Address pc = emitMovePCToReg(scr, gen);
1432
1433     Address varOffset = dest - gen.currAddr();
1434     //printf("VarOffset  = %d\n", varOffset);
1435     //emitLoadRelative(lr, varOffset, scr, gen.width(), gen);
1436
1437     insnCodeGen::generateBranch(gen, gen.currAddr(), dest, true);
1438
1439     return true;
1440     */ 
1441
1442
1443     Address dest = getInterModuleFuncAddr(callee, gen);
1444     Register scr = gen.rs()->getScratchRegister(gen);
1445     Register lr = gen.rs()->getScratchRegister(gen);
1446     //Register scr = gen.rs()->getRegByName("r2");
1447     //Register lr = gen.rs()->getRegByName("r3");
1448     emitMovePCToReg(scr, gen);
1449
1450     Address varOffset = dest - gen.currAddr() + 4;
1451     //printf("VarOffset  = %d\n", varOffset);
1452     emitLoadRelative(lr, varOffset, scr, gen.width(), gen);
1453     insnCodeGen::generateMemAccess(gen, insnCodeGen::Load, lr, lr, 0, 8, insnCodeGen::Offset);
1454
1455     // indirect branch
1456     instruction branchInsn;
1457     branchInsn.clear();
1458
1459     //Set bits which are 0 for both BR and BLR
1460     INSN_SET(branchInsn, 0, 4, 0);
1461     INSN_SET(branchInsn, 10, 15, 0);
1462
1463     //Set register
1464     INSN_SET(branchInsn, 5, 9, lr);
1465
1466     //Set other bits. Basically, these are the opcode bits.
1467     //The only difference between BR and BLR is that bit 21 is 1 for BLR.
1468     INSN_SET(branchInsn, 16, 31, BRegOp);
1469     INSN_SET(branchInsn, 21, 21, 1);
1470     insnCodeGen::generate(gen, branchInsn);
1471     //insnCodeGen::generateBranch(gen, gen.currAddr(), lr, true);
1472     //insnCodeGen::generateBranch(gen, gen.currAddr(), gen.currAddr() +varOffset, true);
1473
1474     return true;
1475
1476     //assert(0); //Not implemented
1477     //return emitPLTCommon(callee, true, gen);
1478 }
1479
1480 bool EmitterAARCH64Stat::emitPLTJump(func_instance *callee, codeGen &gen) {
1481     /*
1482     Address dest = getInterModuleFuncAddr(callee, gen);
1483     //Register scr = gen.rs()->getScratchRegister(gen);
1484     //Register lr = gen.rs()->getScratchRegister(gen);
1485     Register scr = gen.rs()->getRegByName("r2");
1486     Register lr = gen.rs()->getRegByName("r3");
1487     //Address pc = emitMovePCToReg(scr, gen);
1488
1489     Address varOffset = dest - gen.currAddr();
1490     //printf("VarOffset  = %d\n", varOffset);
1491     emitLoadRelative(lr, varOffset, scr, gen.width(), gen);
1492     insnCodeGen::generateMemAccess(gen, insnCodeGen::Load, lr, lr, 0, 8, insnCodeGen::Offset);
1493
1494     insnCodeGen::generateBranch(gen, gen.currAddr(), lr, false);
1495
1496     return true;
1497     */ 
1498
1499     /*
1500     Address dest = getInterModuleFuncAddr(callee, gen);
1501     Register scr = gen.rs()->getScratchRegister(gen);
1502     Register lr = gen.rs()->getScratchRegister(gen);
1503     Address pc = emitMovePCToReg(scr, gen);
1504
1505     Address varOffset = dest - pc;
1506     printf("VarOffset  = %d\n", varOffset);
1507     emitLoadRelative(lr, varOffset, scr, gen.width(), gen);
1508
1509     insnCodeGen::generateBranch(gen, gen.currAddr(), lr, false);
1510     return true;
1511     */
1512     
1513     /*
1514     Address dest = getInterModuleFuncAddr(callee, gen);
1515     Register scr = gen.rs()->getScratchRegister(gen);
1516     Register lr = gen.rs()->getScratchRegister(gen);
1517     Address varOffset = dest - gen.currAddr();
1518     emitLoadRelative(lr, varOffset, scr, gen.width(), gen);
1519     insnCodeGen::generateBranch(gen, gen.currAddr(), gen.currAddr() +varOffset, false);
1520
1521     return true;
1522     */
1523
1524
1525     Address dest = getInterModuleFuncAddr(callee, gen);
1526     Register scr = gen.rs()->getScratchRegister(gen);
1527     Register lr = gen.rs()->getScratchRegister(gen);
1528     //Register scr = gen.rs()->getRegByName("r2");
1529     //Register lr = gen.rs()->getRegByName("r3");
1530     emitMovePCToReg(scr, gen);
1531
1532     Address varOffset = dest - gen.currAddr() + 4;
1533     //printf("VarOffset  = %d\n", varOffset);
1534     emitLoadRelative(lr, varOffset, scr, gen.width(), gen);
1535     insnCodeGen::generateMemAccess(gen, insnCodeGen::Load, lr, lr, 0, 8, insnCodeGen::Offset);
1536
1537     // indirect branch
1538     instruction branchInsn;
1539     branchInsn.clear();
1540
1541     //Set bits which are 0 for both BR and BLR
1542     INSN_SET(branchInsn, 0, 4, 0);
1543     INSN_SET(branchInsn, 10, 15, 0);
1544
1545     //Set register
1546     INSN_SET(branchInsn, 5, 9, lr);
1547
1548     //Set other bits. Basically, these are the opcode bits.
1549     //The only difference between BR and BLR is that bit 21 is 1 for BLR.
1550     INSN_SET(branchInsn, 16, 31, BRegOp);
1551     INSN_SET(branchInsn, 21, 21, 0);
1552     insnCodeGen::generate(gen, branchInsn);
1553     //insnCodeGen::generateBranch(gen, gen.currAddr(), lr, true);
1554     //insnCodeGen::generateBranch(gen, gen.currAddr(), gen.currAddr() +varOffset, true);
1555
1556     return true;
1557
1558     //assert(0); //Not implemented
1559     //return emitPLTCommon(callee, false, gen);
1560 }
1561
1562 bool EmitterAARCH64Stat::emitTOCCall(block_instance *block, codeGen &gen) {
1563     assert(0); //Not implemented
1564     return emitTOCCommon(block, true, gen);
1565 }
1566
1567 bool EmitterAARCH64Stat::emitTOCJump(block_instance *block, codeGen &gen) {
1568     assert(0); //Not implemented
1569     return emitTOCCommon(block, false, gen);
1570 }
1571
1572 bool EmitterAARCH64Stat::emitTOCCommon(block_instance *block, bool call, codeGen &gen) {
1573     assert(0); //Not implemented
1574     return false;
1575 }
1576
1577 bool EmitterAARCH64Stat::emitCallInstruction(codeGen &gen,
1578                                              func_instance *callee,
1579                                              bool setTOC, Address) {
1580     assert(0); //Not implemented
1581     return true;
1582 }
1583
1584 // Generates call instruction sequence for all AARCH64-based systems
1585 // under dynamic instrumentation.
1586 //
1587 // This should be able to stomp on the link register (LR) and TOC
1588 // register (r2), as they were saved by Emitter::emitCall() as necessary.
1589 bool EmitterAARCH64::emitCallInstruction(codeGen &gen, func_instance *callee, bool setTOC, Address toc_anchor) {
1590     assert(0); //Not implemented
1591     return true;
1592 }
1593
1594 void EmitterAARCH64::emitLoadShared(opCode op, Register dest, const image_variable *var, bool is_local, int size,
1595                                     codeGen &gen, Address offset) {
1596     // create or retrieve jump slot
1597     Address addr;
1598     int stackSize = 0;
1599
1600     if(!var) {
1601         addr = offset;
1602     }
1603     else if(!is_local) {
1604         addr = getInterModuleVarAddr(var, gen);
1605     }
1606     else {
1607         addr = (Address)var->getOffset();
1608     }
1609
1610     // load register with address from jump slot
1611     Register scratchReg = gen.rs()->getScratchRegister(gen, true);
1612     assert(scratchReg != REG_NULL && "cannot get a scratch register");
1613
1614     emitMovePCToReg(scratchReg, gen);
1615     Address varOffset = addr - gen.currAddr() + 4;
1616
1617     if (op ==loadOp) {
1618         if(!is_local && (var != NULL)){
1619             emitLoadRelative(dest, varOffset, scratchReg, gen.width(), gen);
1620             // Deference the pointer to get the variable
1621             // emitLoadRelative(dest, 0, dest, size, gen);
1622             // Offset mode to load back to itself
1623             insnCodeGen::generateMemAccess(gen, insnCodeGen::Load, dest, dest, 0, 8, insnCodeGen::Offset);
1624         } else {
1625             emitLoadRelative(dest, varOffset, scratchReg, size, gen);
1626         }
1627     } else { //loadConstop
1628         if(!is_local && (var != NULL)){
1629             emitLoadRelative(dest, varOffset, scratchReg, gen.width(), gen);
1630         } else {
1631             assert(0 && "reached invalid else branch");
1632         }
1633     }
1634
1635     assert(stackSize <= 0 && "stack not empty at the end");
1636 }
1637
1638 void
1639 EmitterAARCH64::emitStoreShared(Register source, const image_variable *var, bool is_local, int size, codeGen &gen) {
1640     // create or retrieve jump slot
1641     Address addr;
1642     int stackSize = 0;
1643     if(!is_local) {
1644         addr = getInterModuleVarAddr(var, gen);
1645     }
1646     else {
1647         addr = (Address)var->getOffset();
1648     }
1649
1650     // load register with address from jump slot
1651     Register scratchReg = gen.rs()->getScratchRegister(gen, true);
1652     assert(scratchReg != REG_NULL && "cannot get a scratch register");
1653
1654     emitMovePCToReg(scratchReg, gen);
1655     Address varOffset = addr - gen.currAddr() + 4;
1656
1657     if(!is_local) {
1658         pdvector<Register> exclude;
1659         exclude.push_back(scratchReg);
1660         Register scratchReg1 = gen.rs()->getScratchRegister(gen, exclude, true);
1661         assert(scratchReg1 != REG_NULL && "cannot get a scratch register");
1662         emitLoadRelative(scratchReg1, varOffset, scratchReg, gen.width(), gen);
1663         emitStoreRelative(source, 0, scratchReg1, size, gen);
1664     } else {
1665         emitStoreRelative(source, varOffset, scratchReg, size, gen);
1666     }
1667
1668     assert(stackSize <= 0 && "stack not empty at the end");
1669 }
1670
1671 Address Emitter::getInterModuleVarAddr(const image_variable *var, codeGen &gen) {
1672     AddressSpace *addrSpace = gen.addrSpace();
1673     if (!addrSpace)
1674         assert(0 && "No AddressSpace associated with codeGen object");
1675
1676     BinaryEdit *binEdit = addrSpace->edit();
1677     Address relocation_address;
1678
1679     unsigned int jump_slot_size;
1680     switch (addrSpace->getAddressWidth()) {
1681         case 4: jump_slot_size = 4; break;
1682         case 8: jump_slot_size = 8; break;
1683         default: assert(0 && "Encountered unknown address width");
1684     }
1685
1686     if (!binEdit || !var) {
1687         assert(!"Invalid variable load (variable info is missing)");
1688     }
1689
1690     // find the Symbol corresponding to the int_variable
1691     std::vector<SymtabAPI::Symbol *> syms;
1692     var->svar()->getSymbols(syms);
1693
1694     if (syms.size() == 0) {
1695         char msg[256];
1696         snprintf(msg, sizeof(msg), "%s[%d]:  internal error:  cannot find symbol %s"
1697                 , __FILE__, __LINE__, var->symTabName().c_str());
1698         showErrorCallback(80, msg);
1699         assert(0);
1700     }
1701
1702     // try to find a dynamic symbol
1703     // (take first static symbol if none are found)
1704     SymtabAPI::Symbol *referring = syms[0];
1705     for (unsigned k=0; k<syms.size(); k++) {
1706         if (syms[k]->isInDynSymtab()) {
1707             referring = syms[k];
1708             break;
1709         }
1710     }
1711
1712     // have we added this relocation already?
1713     relocation_address = binEdit->getDependentRelocationAddr(referring);
1714
1715     if (!relocation_address) {
1716         // inferiorMalloc addr location and initialize to zero
1717         relocation_address = binEdit->inferiorMalloc(jump_slot_size);
1718         unsigned char dat[8] = {0};
1719         binEdit->writeDataSpace((void*)relocation_address, jump_slot_size, dat);
1720
1721         // add write new relocation symbol/entry
1722         binEdit->addDependentRelocation(relocation_address, referring);
1723     }
1724
1725     return relocation_address;
1726 }
1727
1728 Address EmitterAARCH64::emitMovePCToReg(Register dest, codeGen &gen) {
1729     instruction insn;
1730     insn.clear();
1731
1732     INSN_SET(insn, 28, 28, 1);
1733     INSN_SET(insn, 0, 4, dest);
1734
1735     insnCodeGen::generate(gen, insn);
1736     Address ret = gen.currAddr();
1737     return ret;
1738 }
1739
1740 Address Emitter::getInterModuleFuncAddr(func_instance *func, codeGen &gen) {
1741     // from POWER64 getInterModuleFuncAddr
1742
1743     AddressSpace *addrSpace = gen.addrSpace();
1744     if (!addrSpace)
1745         assert(0 && "No AddressSpace associated with codeGen object");
1746
1747     BinaryEdit *binEdit = addrSpace->edit();
1748     Address relocation_address;
1749     
1750     unsigned int jump_slot_size;
1751     switch (addrSpace->getAddressWidth()) {
1752     case 4: jump_slot_size =  4; break; // l: not needed
1753     case 8: 
1754       jump_slot_size = 24;
1755       break;
1756     default: assert(0 && "Encountered unknown address width");
1757     }
1758
1759     if (!binEdit || !func) {
1760         assert(!"Invalid function call (function info is missing)");
1761     }
1762
1763     // find the Symbol corresponding to the func_instance
1764     std::vector<SymtabAPI::Symbol *> syms;
1765     func->ifunc()->func()->getSymbols(syms);
1766
1767     if (syms.size() == 0) {
1768         char msg[256];
1769         snprintf(msg, sizeof(msg), "%s[%d]:  internal error:  cannot find symbol %s"
1770                 , __FILE__, __LINE__, func->symTabName().c_str());
1771         showErrorCallback(80, msg);
1772         assert(0);
1773     }
1774
1775     // try to find a dynamic symbol
1776     // (take first static symbol if none are found)
1777     SymtabAPI::Symbol *referring = syms[0];
1778     for (unsigned k=0; k<syms.size(); k++) {
1779         if (syms[k]->isInDynSymtab()) {
1780             referring = syms[k];
1781             break;
1782         }
1783     }
1784     // have we added this relocation already?
1785     relocation_address = binEdit->getDependentRelocationAddr(referring);
1786
1787     if (!relocation_address) {
1788         // inferiorMalloc addr location and initialize to zero
1789         relocation_address = binEdit->inferiorMalloc(jump_slot_size);
1790         unsigned char dat[24] = {0};
1791         binEdit->writeDataSpace((void*)relocation_address, jump_slot_size, dat);
1792         // add write new relocation symbol/entry
1793         binEdit->addDependentRelocation(relocation_address, referring);
1794     }
1795     return relocation_address;
1796 }
1797
1798
1799
1800