Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(28)

Unified Diff: src/arm/assembler-thumb2.h

Issue 601028: Forking disassembler and simulator for Thumb2 support;... Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/arm/assembler-arm.h ('k') | src/arm/assembler-thumb2-inl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm/assembler-thumb2.h
===================================================================
--- src/arm/assembler-thumb2.h (revision 3826)
+++ src/arm/assembler-thumb2.h (working copy)
@@ -30,9 +30,9 @@
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
-// The original source code covered by the above license above has been modified
+// The original source code covered by the above license has been modified
// significantly by Google Inc.
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2010 the V8 project authors. All rights reserved.
// A light-weight ARM Assembler
// Generates user mode instructions for the ARM architecture up to version 5
@@ -46,6 +46,138 @@
namespace v8 {
namespace internal {
+// The beginning of this file contains some enum declarations that are
+// redundant with declarations in constants-arm.h, but in a different namespace
+// Please keep the order and values consistent, so we can merge the files
+// later easily.
+
+// Opcodes for Data-processing instructions (instructions with a type 0 and 1)
+// as defined in section A3.4
+enum Opcode {
+ no_operand = -1,
+ AND = 0, // Logical AND
+ EOR = 1, // Logical Exclusive OR
+ SUB = 2, // Subtract
+ RSB = 3, // Reverse Subtract
+ ADD = 4, // Add
+ ADC = 5, // Add with Carry
+ SBC = 6, // Subtract with Carry
+ RSC = 7, // Reverse Subtract with Carry
+ TST = 8, // Test
+ TEQ = 9, // Test Equivalence
+ CMP = 10, // Compare
+ CMN = 11, // Compare Negated
+ ORR = 12, // Logical (inclusive) OR
+ MOV = 13, // Move
+ BIC = 14, // Bit Clear
+ MVN = 15, // Move Not
+ max_operand = 16
+};
+
+enum BitPositions {
+ B0 = 1 << 0,
+ B1 = 1 << 1,
+ B2 = 1 << 2,
+ B3 = 1 << 3,
+ B4 = 1 << 4,
+ B5 = 1 << 5,
+ B6 = 1 << 6,
+ B7 = 1 << 7,
+ B8 = 1 << 8,
+ B9 = 1 << 9,
+ B10 = 1 << 10,
+ B11 = 1 << 11,
+ B12 = 1 << 12,
+ B16 = 1 << 16,
+ B18 = 1 << 18,
+ B19 = 1 << 19,
+ B20 = 1 << 20,
+ B21 = 1 << 21,
+ B22 = 1 << 22,
+ B23 = 1 << 23,
+ B24 = 1 << 24,
+ B25 = 1 << 25,
+ B26 = 1 << 26,
+ B27 = 1 << 27
+};
+
+enum Bits1 {
+ b0 = 0x0,
+ b1 = 0x1
+};
+
+enum Bits2 {
+ b00 = 0x0,
+ b01 = 0x1,
+ b10 = 0x2,
+ b11 = 0x3
+};
+
+enum Bits3 {
+ b000 = 0x0,
+ b001 = 0x1,
+ b010 = 0x2,
+ b011 = 0x3,
+ b100 = 0x4,
+ b101 = 0x5,
+ b110 = 0x6,
+ b111 = 0x7
+};
+
+enum Bits4 {
+ b0000 = 0x0,
+ b0001 = 0x1,
+ b0010 = 0x2,
+ b0011 = 0x3,
+ b0100 = 0x4,
+ b0101 = 0x5,
+ b0110 = 0x6,
+ b0111 = 0x7,
+ b1000 = 0x8,
+ b1001 = 0x9,
+ b1010 = 0xa,
+ b1011 = 0xb,
+ b1100 = 0xc,
+ b1101 = 0xd,
+ b1110 = 0xe,
+ b1111 = 0xf
+};
+
+enum Bits5 {
+ b00000 = 0x00,
+ b00001 = 0x01,
+ b00010 = 0x02,
+ b00011 = 0x03,
+ b00100 = 0x04,
+ b00101 = 0x05,
+ b00110 = 0x06,
+ b00111 = 0x07,
+ b01000 = 0x08,
+ b01001 = 0x09,
+ b01010 = 0x0a,
+ b01011 = 0x0b,
+ b01100 = 0x0c,
+ b01101 = 0x0d,
+ b01110 = 0x0e,
+ b01111 = 0x0f,
+ b10000 = 0x10,
+ b10001 = 0x11,
+ b10010 = 0x12,
+ b10011 = 0x13,
+ b10100 = 0x14,
+ b10101 = 0x15,
+ b10110 = 0x16,
+ b10111 = 0x17,
+ b11000 = 0x18,
+ b11001 = 0x19,
+ b11010 = 0x1a,
+ b11011 = 0x1b,
+ b11100 = 0x1c,
+ b11101 = 0x1d,
+ b11110 = 0x1e,
+ b11111 = 0x1f
+};
+
// CPU Registers.
//
// 1) We would prefer to use an enum, but enum values are assignment-
@@ -250,7 +382,7 @@
};
-// Condition field in instructions
+// Condition field in instructions.
enum Condition {
eq = 0 << 28, // Z set equal.
ne = 1 << 28, // Z clear not equal.
@@ -316,10 +448,10 @@
// Shifter operand shift operation
enum ShiftOp {
- LSL = 0 << 5,
- LSR = 1 << 5,
- ASR = 2 << 5,
- ROR = 3 << 5,
+ LSL = 0,
+ LSR = 1,
+ ASR = 2,
+ ROR = 3,
RRX = -1
};
@@ -506,14 +638,16 @@
static unsigned found_by_runtime_probing_;
};
+typedef int32_t InstrArm;
+typedef int16_t InstrThumb;
-typedef int32_t Instr;
+// hack to keep the code patcher happy for now
+typedef InstrArm Instr;
+extern const InstrArm kMovLrPc;
+extern const InstrArm kLdrPCPattern;
-extern const Instr kMovLrPc;
-extern const Instr kLdrPCPattern;
-
class Assembler : public Malloced {
public:
// Create an assembler. Instructions and relocation information are emitted
@@ -589,15 +723,19 @@
static const int kExternalTargetSize = kPointerSize;
// Size of an instruction.
+ static const int kInstrArmSize = sizeof(InstrArm);
+ static const int kInstrThumbSize = sizeof(InstrThumb);
+ // Keep the code generator happy for now.
static const int kInstrSize = sizeof(Instr);
+
// Distance between the instruction referring to the address of the call
// target (ldr pc, [target addr in const pool]) and the return address
- static const int kCallTargetAddressOffset = kInstrSize;
+ static const int kCallTargetAddressOffset = kInstrArmSize;
// Distance between start of patched return sequence and the emitted address
// to jump to.
- static const int kPatchReturnSequenceAddressOffset = kInstrSize;
+ static const int kPatchReturnSequenceAddressOffset = kInstrArmSize;
// Difference between address of current opcode and value read from pc
// register.
@@ -630,6 +768,9 @@
void blx(Label* L) { blx(branch_offset(L, false)); } // v5 and above
// Data-processing instructions
+ void ubfx(Register dst, Register src1, const Operand& src2,
+ const Operand& src3, Condition cond = al);
+
void and_(Register dst, Register src1, const Operand& src2,
SBit s = LeaveCC, Condition cond = al);
@@ -796,6 +937,14 @@
// However, some simple modifications can allow
// these APIs to support D16 to D31.
+ void vldr(const DwVfpRegister dst,
+ const Register base,
+ int offset, // Offset must be a multiple of 4.
+ const Condition cond = al);
+ void vstr(const DwVfpRegister src,
+ const Register base,
+ int offset, // Offset must be a multiple of 4.
+ const Condition cond = al);
void vmov(const DwVfpRegister dst,
const Register src1,
const Register src2,
@@ -864,7 +1013,7 @@
// Check the code size generated from label to here.
int InstructionsGeneratedSince(Label* l) {
- return (pc_offset() - l->pos()) / kInstrSize;
+ return (pc_offset() - l->pos()) / kInstrArmSize;
}
// Check whether an immediate fits an addressing mode 1 instruction.
@@ -895,15 +1044,22 @@
int buffer_space() const { return reloc_info_writer.pos() - pc_; }
// Read/patch instructions
- static Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); }
- void instr_at_put(byte* pc, Instr instr) {
- *reinterpret_cast<Instr*>(pc) = instr;
+ static InstrArm instr_arm_at(byte* pc) {
+ return *reinterpret_cast<InstrArm*>(pc);
}
- Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); }
- void instr_at_put(int pos, Instr instr) {
- *reinterpret_cast<Instr*>(buffer_ + pos) = instr;
+
+ void instr_arm_at_put(byte* pc, InstrArm instr) {
+ *reinterpret_cast<InstrArm*>(pc) = instr;
}
+ InstrArm instr_arm_at(int pos) {
+ return *reinterpret_cast<InstrArm*>(buffer_ + pos);
+ }
+
+ void instr_arm_at_put(int pos, InstrArm instr) {
+ *reinterpret_cast<InstrArm*>(buffer_ + pos) = instr;
+ }
+
// Decode branch instruction at pos and return branch target pos
int target_at(int pos);
@@ -954,7 +1110,8 @@
// has been generated. That also means that the sizing of the buffers is not
// an exact science, and that we rely on some slop to not overrun buffers.
static const int kCheckConstIntervalInst = 32;
- static const int kCheckConstInterval = kCheckConstIntervalInst * kInstrSize;
+ static const int kCheckConstInterval =
+ kCheckConstIntervalInst * kInstrArmSize;
// Pools are emitted after function return and in dead code at (more or less)
@@ -983,7 +1140,7 @@
// stored in a separate buffer until a constant pool is emitted.
// If every instruction in a long sequence is accessing the pool, we need one
// pending relocation entry per instruction.
- static const int kMaxNumPRInfo = kMaxDistBetweenPools/kInstrSize;
+ static const int kMaxNumPRInfo = kMaxDistBetweenPools/kInstrArmSize;
RelocInfo prinfo_[kMaxNumPRInfo]; // the buffer of pending relocation info
int num_prinfo_; // number of pending reloc info entries in the buffer
@@ -995,19 +1152,32 @@
int current_statement_position_;
int written_position_;
int written_statement_position_;
+ bool thumb_mode_;
+
// Code emission
inline void CheckBuffer();
+ inline void EnsureThumbMode();
+ inline void EnsureArmMode();
void GrowBuffer();
- inline void emit(Instr x);
+ inline void emit_thumb(InstrThumb x);
+ inline void emit_arm(InstrArm x);
+ inline void emit_int32(int32_t x);
- // Instruction generation
- void addrmod1(Instr instr, Register rn, Register rd, const Operand& x);
- void addrmod2(Instr instr, Register rd, const MemOperand& x);
- void addrmod3(Instr instr, Register rd, const MemOperand& x);
- void addrmod4(Instr instr, Register rn, RegList rl);
- void addrmod5(Instr instr, CRegister crd, const MemOperand& x);
+ // ARM Instruction generation
+ void addrmod1(InstrArm instr, Register rn, Register rd, const Operand& x);
+ void addrmod2(InstrArm instr, Register rd, const MemOperand& x);
+ void addrmod3(InstrArm instr, Register rd, const MemOperand& x);
+ void addrmod4(InstrArm instr, Register rn, RegList rl);
+ void addrmod5(InstrArm instr, CRegister crd, const MemOperand& x);
+ // Thumb2 Instruction generation
+ void DataProcessing(Condition cond, Opcode op, SBit s,
+ Register rn, Register rd, const Operand& x);
+ void DataProcessingReg(Opcode op, SBit s, Register rn, Register rd,
+ Register rm, ShiftOp shiftOp, int shiftBy);
+ void DataProcessingImm(Opcode op, SBit s, Register rn, Register rd, int imm);
+
// Labels
void print(Label* L);
void bind_to(Label* L, int pos);
« no previous file with comments | « src/arm/assembler-arm.h ('k') | src/arm/assembler-thumb2-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698