Chromium Code Reviews| Index: src/IceInstARM32.h |
| diff --git a/src/IceInstARM32.h b/src/IceInstARM32.h |
| index 75f48a7ff82f70f07d356c834d8c6ed8e20e522b..d9f7dc4ae87f52345ea4a9bd808eb212e579d4ab 100644 |
| --- a/src/IceInstARM32.h |
| +++ b/src/IceInstARM32.h |
| @@ -27,6 +27,12 @@ |
| namespace Ice { |
| namespace ARM32 { |
| +/// Encoding of an ARM 32-bit instruction. |
| +using IValueT = uint32_t; |
| + |
| +/// An Offset value (+/-) used in an ARM 32-bit instruction. |
| +using IOffsetT = int32_t; |
| + |
| class TargetARM32; |
| /// OperandARM32 extends the Operand hierarchy. Its subclasses are |
| @@ -364,6 +370,9 @@ class InstARM32 : public InstTarget { |
| InstARM32 &operator=(const InstARM32 &) = delete; |
| public: |
| + // Defines form that assembly instruction should be synthesized. |
| + enum OutputForm { TextualOutput, BinaryOutput }; |
|
Jim Stichnoth
2016/01/10 18:21:59
My preference (as littered throughout the code bas
John
2016/01/11 13:40:36
I am not a fan of these prefixes myself (they are
Karl
2016/01/11 17:59:44
Acknowledged.
Karl
2016/01/11 17:59:44
Done.
|
| + |
| enum InstKindARM32 { |
| k__Start = Inst::Target, |
| Adc, |
| @@ -1055,9 +1064,39 @@ private: |
| InstARM32Call(Cfg *Func, Variable *Dest, Operand *CallTarget); |
| }; |
| +class InstARM32RegisterStackOp : public InstARM32 { |
| + InstARM32RegisterStackOp() = delete; |
| + InstARM32RegisterStackOp(const InstARM32RegisterStackOp &) = delete; |
| + InstARM32RegisterStackOp & |
| + operator=(const InstARM32RegisterStackOp &) = delete; |
| + |
| +public: |
| + void emit(const Cfg *Func) const override; |
| + void emitIAS(const Cfg *Func) const override; |
| + void dump(const Cfg *Func) const override; |
| + |
| +protected: |
| + InstARM32RegisterStackOp(Cfg *Func, InstKindARM32 Kind, SizeT Maxsrcs, |
| + Variable *Dest) |
| + : InstARM32(Func, Kind, Maxsrcs, Dest) {} |
| + void emitUsingForm(const Cfg *Func, const OutputForm Form) const; |
| + void emitGPRsAsText(const Cfg *Func) const; |
| + void emitSRegsAsText(const Cfg *Func, const Variable *BaseReg, |
| + SizeT Regcount) const; |
| + virtual const char *getOpcode() const = 0; |
| + virtual Variable *getStackReg(SizeT Index) const = 0; |
| + virtual SizeT getNumStackRegs() const = 0; |
| + virtual void emitSingleGPR(const Cfg *Func, const OutputForm Form, |
| + const Variable *Reg) const = 0; |
| + virtual void emitMultipleGPRs(const Cfg *Func, const OutputForm Form, |
| + IValueT Registers) const = 0; |
| + virtual void emitSRegs(const Cfg *Func, const OutputForm Form, |
| + const Variable *BaseReg, SizeT RegCount) const = 0; |
| +}; |
| + |
| /// Pops a list of registers. It may be a list of GPRs, or a list of VFP "s" |
| /// regs, but not both. In any case, the list must be sorted. |
| -class InstARM32Pop : public InstARM32 { |
| +class InstARM32Pop : public InstARM32RegisterStackOp { |
| InstARM32Pop() = delete; |
| InstARM32Pop(const InstARM32Pop &) = delete; |
| InstARM32Pop &operator=(const InstARM32Pop &) = delete; |
| @@ -1066,20 +1105,26 @@ public: |
| static InstARM32Pop *create(Cfg *Func, const VarList &Dests) { |
| return new (Func->allocate<InstARM32Pop>()) InstARM32Pop(Func, Dests); |
| } |
| - void emit(const Cfg *Func) const override; |
| - void emitIAS(const Cfg *Func) const override; |
| - void dump(const Cfg *Func) const override; |
| static bool classof(const Inst *Inst) { return isClassof(Inst, Pop); } |
| private: |
| InstARM32Pop(Cfg *Func, const VarList &Dests); |
| + virtual const char *getOpcode() const final; |
| + Variable *getStackReg(SizeT Index) const final; |
| + SizeT getNumStackRegs() const final; |
| + void emitSingleGPR(const Cfg *Func, const OutputForm Form, |
| + const Variable *Reg) const final; |
| + void emitMultipleGPRs(const Cfg *Func, const OutputForm Form, |
| + IValueT Registers) const final; |
| + void emitSRegs(const Cfg *Func, const OutputForm Form, |
| + const Variable *BaseReg, SizeT RegCount) const final; |
| VarList Dests; |
| }; |
| /// Pushes a list of registers. Just like Pop (see above), the list may be of |
| /// GPRs, or VFP "s" registers, but not both. |
| -class InstARM32Push : public InstARM32 { |
| +class InstARM32Push : public InstARM32RegisterStackOp { |
| InstARM32Push() = delete; |
| InstARM32Push(const InstARM32Push &) = delete; |
| InstARM32Push &operator=(const InstARM32Push &) = delete; |
| @@ -1088,13 +1133,19 @@ public: |
| static InstARM32Push *create(Cfg *Func, const VarList &Srcs) { |
| return new (Func->allocate<InstARM32Push>()) InstARM32Push(Func, Srcs); |
| } |
| - void emit(const Cfg *Func) const override; |
| - void emitIAS(const Cfg *Func) const override; |
| - void dump(const Cfg *Func) const override; |
| static bool classof(const Inst *Inst) { return isClassof(Inst, Push); } |
| private: |
| InstARM32Push(Cfg *Func, const VarList &Srcs); |
| + const char *getOpcode() const final; |
| + Variable *getStackReg(SizeT Index) const final; |
| + SizeT getNumStackRegs() const final; |
| + void emitSingleGPR(const Cfg *Func, const OutputForm Form, |
| + const Variable *Reg) const final; |
| + void emitMultipleGPRs(const Cfg *Func, const OutputForm Form, |
| + IValueT Registers) const final; |
| + void emitSRegs(const Cfg *Func, const OutputForm Form, |
| + const Variable *BaseReg, SizeT RegCount) const final; |
| }; |
| /// Ret pseudo-instruction. This is actually a "bx" instruction with an "lr" |