* Copyright (C) 2005 by Dominic Rath
* Dominic.Rath@gmx.de
*
+ * Copyright (C) 2006 by Magnus Lundin
+ * lundin@mlu.mine.nu
+ *
* Copyright (C) 2008 by Spencer Oliver
* spen@spen-soft.co.uk
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the
* Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __ARM_OPCODES_H
#define __ARM_OPCODES_H
+/**
+ * @file
+ * Macros used to generate various ARM or Thumb opcodes.
+ */
+
/* ARM mode instructions */
/* Store multiple increment after
#define ARMV4_5_MSR_IM(Im, Rotate, Field, R) \
(0xe320f000 | (Im) | ((Rotate) << 8) | ((Field) << 16) | ((R) << 22))
+/* Load Register Word Immediate Post-Index
+ * Rd: register to load
+ * Rn: base register
+ */
+#define ARMV4_5_LDRW_IP(Rd, Rn) (0xe4900004 | ((Rd) << 12) | ((Rn) << 16))
+
/* Load Register Halfword Immediate Post-Index
* Rd: register to load
* Rn: base register
*/
#define ARMV4_5_LDRB_IP(Rd, Rn) (0xe4d00001 | ((Rd) << 12) | ((Rn) << 16))
+/* Store register Word Immediate Post-Index
+ * Rd: register to store
+ * Rn: base register
+ */
+#define ARMV4_5_STRW_IP(Rd, Rn) (0xe4800004 | ((Rd) << 12) | ((Rn) << 16))
+
/* Store register Halfword Immediate Post-Index
* Rd: register to store
* Rn: base register
*/
#define ARMV4_5_BX(Rm) (0xe12fff10 | (Rm))
+/* Store data from coprocessor to consecutive memory
+ * See Armv7-A arch doc section A8.6.187
+ * P: 1=index mode (offset from Rn)
+ * U: 1=add, 0=subtract Rn address with imm
+ * D: Opcode D encoding
+ * W: write back the offset start address to the Rn register
+ * CP: Coprocessor number (4 bits)
+ * CRd: Coprocessor source register (4 bits)
+ * Rn: Base register for memory address (4 bits)
+ * imm: Immediate value (0 - 1020, must be divisible by 4)
+ */
+#define ARMV4_5_STC(P, U, D, W, CP, CRd, Rn, imm) \
+ (0xec000000 | ((P) << 24) | ((U) << 23) | ((D) << 22) | \
+ ((W) << 21) | ((Rn) << 16) | ((CRd) << 12) | ((CP) << 8) | ((imm)>>2))
+
+/* Loads data from consecutive memory to coprocessor
+ * See Armv7-A arch doc section A8.6.51
+ * P: 1=index mode (offset from Rn)
+ * U: 1=add, 0=subtract Rn address with imm
+ * D: Opcode D encoding
+ * W: write back the offset start address to the Rn register
+ * CP: Coprocessor number (4 bits)
+ * CRd: Coprocessor dest register (4 bits)
+ * Rn: Base register for memory address (4 bits)
+ * imm: Immediate value (0 - 1020, must be divisible by 4)
+ */
+#define ARMV4_5_LDC(P, U, D, W, CP, CRd, Rn, imm) \
+ (0xec100000 | ((P) << 24) | ((U) << 23) | ((D) << 22) | \
+ ((W) << 21) | ((Rn) << 16) | ((CRd) << 12) | ((CP) << 8) | ((imm) >> 2))
+
/* Move to ARM register from coprocessor
* CP: Coprocessor number
* op1: Coprocessor opcode
/* Thumb mode instructions
*
- * FIXME there must be some reason all these opcodes are 32-bits
- * not 16-bits ... this should get either an explanatory comment,
- * or be changed not to duplicate the opcode.
+ * NOTE: these 16-bit opcodes fill both halves of a word with the same
+ * value. The reason for this is that when we need to execute Thumb
+ * opcodes on ARM7/ARM9 cores (to switch to ARM state on debug entry),
+ * we must shift 32 bits to the bus using scan chain 1 ... if we write
+ * both halves, we don't need to track which half matters. On ARMv6 and
+ * ARMv7 we don't execute Thumb instructions in debug mode; the ITR
+ * register does not accept Thumb (or Thumb2) opcodes.
*/
/* Store register (Thumb mode)