You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

273 lines
7.7 KiB

  1. /*
  2. * Copyright (C) 2005 by Dominic Rath
  3. * Dominic.Rath@gmx.de
  4. *
  5. * Copyright (C) 2006 by Magnus Lundin
  6. * lundin@mlu.mine.nu
  7. *
  8. * Copyright (C) 2008 by Spencer Oliver
  9. * spen@spen-soft.co.uk
  10. *
  11. * Copyright (C) 2009 by √ėyvind Harboe
  12. * oyvind.harboe@zylin.com
  13. *
  14. * This program is free software; you can redistribute it and/or modify
  15. * it under the terms of the GNU General Public License as published by
  16. * the Free Software Foundation; either version 2 of the License, or
  17. * (at your option) any later version.
  18. *
  19. * This program is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU General Public License
  25. * along with this program; if not, write to the
  26. * Free Software Foundation, Inc.,
  27. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  28. */
  29. #ifndef __ARM_OPCODES_H
  30. #define __ARM_OPCODES_H
  31. /**
  32. * @file
  33. * Macros used to generate various ARM or Thumb opcodes.
  34. */
  35. /* ARM mode instructions */
  36. /* Store multiple increment after
  37. * Rn: base register
  38. * List: for each bit in list: store register
  39. * S: in priviledged mode: store user-mode registers
  40. * W = 1: update the base register. W = 0: leave the base register untouched
  41. */
  42. #define ARMV4_5_STMIA(Rn, List, S, W) \
  43. (0xe8800000 | ((S) << 22) | ((W) << 21) | ((Rn) << 16) | (List))
  44. /* Load multiple increment after
  45. * Rn: base register
  46. * List: for each bit in list: store register
  47. * S: in priviledged mode: store user-mode registers
  48. * W = 1: update the base register. W = 0: leave the base register untouched
  49. */
  50. #define ARMV4_5_LDMIA(Rn, List, S, W) \
  51. (0xe8900000 | ((S) << 22) | ((W) << 21) | ((Rn) << 16) | (List))
  52. /* MOV r8, r8 */
  53. #define ARMV4_5_NOP (0xe1a08008)
  54. /* Move PSR to general purpose register
  55. * R = 1: SPSR R = 0: CPSR
  56. * Rn: target register
  57. */
  58. #define ARMV4_5_MRS(Rn, R) (0xe10f0000 | ((R) << 22) | ((Rn) << 12))
  59. /* Store register
  60. * Rd: register to store
  61. * Rn: base register
  62. */
  63. #define ARMV4_5_STR(Rd, Rn) (0xe5800000 | ((Rd) << 12) | ((Rn) << 16))
  64. /* Load register
  65. * Rd: register to load
  66. * Rn: base register
  67. */
  68. #define ARMV4_5_LDR(Rd, Rn) (0xe5900000 | ((Rd) << 12) | ((Rn) << 16))
  69. /* Move general purpose register to PSR
  70. * R = 1: SPSR R = 0: CPSR
  71. * Field: Field mask
  72. * 1: control field 2: extension field 4: status field 8: flags field
  73. * Rm: source register
  74. */
  75. #define ARMV4_5_MSR_GP(Rm, Field, R) \
  76. (0xe120f000 | (Rm) | ((Field) << 16) | ((R) << 22))
  77. #define ARMV4_5_MSR_IM(Im, Rotate, Field, R) \
  78. (0xe320f000 | (Im) | ((Rotate) << 8) | ((Field) << 16) | ((R) << 22))
  79. /* Load Register Halfword Immediate Post-Index
  80. * Rd: register to load
  81. * Rn: base register
  82. */
  83. #define ARMV4_5_LDRH_IP(Rd, Rn) (0xe0d000b2 | ((Rd) << 12) | ((Rn) << 16))
  84. /* Load Register Byte Immediate Post-Index
  85. * Rd: register to load
  86. * Rn: base register
  87. */
  88. #define ARMV4_5_LDRB_IP(Rd, Rn) (0xe4d00001 | ((Rd) << 12) | ((Rn) << 16))
  89. /* Store register Halfword Immediate Post-Index
  90. * Rd: register to store
  91. * Rn: base register
  92. */
  93. #define ARMV4_5_STRH_IP(Rd, Rn) (0xe0c000b2 | ((Rd) << 12) | ((Rn) << 16))
  94. /* Store register Byte Immediate Post-Index
  95. * Rd: register to store
  96. * Rn: base register
  97. */
  98. #define ARMV4_5_STRB_IP(Rd, Rn) (0xe4c00001 | ((Rd) << 12) | ((Rn) << 16))
  99. /* Branch (and Link)
  100. * Im: Branch target (left-shifted by 2 bits, added to PC)
  101. * L: 1: branch and link 0: branch only
  102. */
  103. #define ARMV4_5_B(Im, L) (0xea000000 | (Im) | ((L) << 24))
  104. /* Branch and exchange (ARM state)
  105. * Rm: register holding branch target address
  106. */
  107. #define ARMV4_5_BX(Rm) (0xe12fff10 | (Rm))
  108. /* Move to ARM register from coprocessor
  109. * CP: Coprocessor number
  110. * op1: Coprocessor opcode
  111. * Rd: destination register
  112. * CRn: first coprocessor operand
  113. * CRm: second coprocessor operand
  114. * op2: Second coprocessor opcode
  115. */
  116. #define ARMV4_5_MRC(CP, op1, Rd, CRn, CRm, op2) \
  117. (0xee100010 | (CRm) | ((op2) << 5) | ((CP) << 8) \
  118. | ((Rd) << 12) | ((CRn) << 16) | ((op1) << 21))
  119. /* Move to coprocessor from ARM register
  120. * CP: Coprocessor number
  121. * op1: Coprocessor opcode
  122. * Rd: destination register
  123. * CRn: first coprocessor operand
  124. * CRm: second coprocessor operand
  125. * op2: Second coprocessor opcode
  126. */
  127. #define ARMV4_5_MCR(CP, op1, Rd, CRn, CRm, op2) \
  128. (0xee000010 | (CRm) | ((op2) << 5) | ((CP) << 8) \
  129. | ((Rd) << 12) | ((CRn) << 16) | ((op1) << 21))
  130. /* Breakpoint instruction (ARMv5)
  131. * Im: 16-bit immediate
  132. */
  133. #define ARMV5_BKPT(Im) (0xe1200070 | ((Im & 0xfff0) << 8) | (Im & 0xf))
  134. /* Thumb mode instructions
  135. *
  136. * NOTE: these 16-bit opcodes fill both halves of a word with the same
  137. * value. The reason for this is that when we need to execute Thumb
  138. * opcodes on ARM7/ARM9 cores (to switch to ARM state on debug entry),
  139. * we must shift 32 bits to the bus using scan chain 1 ... if we write
  140. * both halves, we don't need to track which half matters. On ARMv6 and
  141. * ARMv7 we don't execute Thumb instructions in debug mode; the ITR
  142. * register does not accept Thumb (or Thumb2) opcodes.
  143. */
  144. /* Store register (Thumb mode)
  145. * Rd: source register
  146. * Rn: base register
  147. */
  148. #define ARMV4_5_T_STR(Rd, Rn) \
  149. ((0x6000 | (Rd) | ((Rn) << 3)) | \
  150. ((0x6000 | (Rd) | ((Rn) << 3)) << 16))
  151. /* Load register (Thumb state)
  152. * Rd: destination register
  153. * Rn: base register
  154. */
  155. #define ARMV4_5_T_LDR(Rd, Rn) \
  156. ((0x6800 | ((Rn) << 3) | (Rd)) \
  157. | ((0x6800 | ((Rn) << 3) | (Rd)) << 16))
  158. /* Load multiple (Thumb state)
  159. * Rn: base register
  160. * List: for each bit in list: store register
  161. */
  162. #define ARMV4_5_T_LDMIA(Rn, List) \
  163. ((0xc800 | ((Rn) << 8) | (List)) \
  164. | ((0xc800 | ((Rn) << 8) | (List)) << 16))
  165. /* Load register with PC relative addressing
  166. * Rd: register to load
  167. */
  168. #define ARMV4_5_T_LDR_PCREL(Rd) \
  169. ((0x4800 | ((Rd) << 8)) \
  170. | ((0x4800 | ((Rd) << 8)) << 16))
  171. /* Move hi register (Thumb mode)
  172. * Rd: destination register
  173. * Rm: source register
  174. */
  175. #define ARMV4_5_T_MOV(Rd, Rm) \
  176. ((0x4600 | ((Rd) & 0x7) | (((Rd) & 0x8) << 4) | \
  177. (((Rm) & 0x7) << 3) | (((Rm) & 0x8) << 3)) \
  178. | ((0x4600 | ((Rd) & 0x7) | (((Rd) & 0x8) << 4) | \
  179. (((Rm) & 0x7) << 3) | (((Rm) & 0x8) << 3)) << 16))
  180. /* No operation (Thumb mode)
  181. * NOTE: this is "MOV r8, r8" ... Thumb2 adds two
  182. * architected NOPs, 16-bit and 32-bit.
  183. */
  184. #define ARMV4_5_T_NOP (0x46c0 | (0x46c0 << 16))
  185. /* Move immediate to register (Thumb state)
  186. * Rd: destination register
  187. * Im: 8-bit immediate value
  188. */
  189. #define ARMV4_5_T_MOV_IM(Rd, Im) \
  190. ((0x2000 | ((Rd) << 8) | (Im)) \
  191. | ((0x2000 | ((Rd) << 8) | (Im)) << 16))
  192. /* Branch and Exchange
  193. * Rm: register containing branch target
  194. */
  195. #define ARMV4_5_T_BX(Rm) \
  196. ((0x4700 | ((Rm) << 3)) \
  197. | ((0x4700 | ((Rm) << 3)) << 16))
  198. /* Branch (Thumb state)
  199. * Imm: Branch target
  200. */
  201. #define ARMV4_5_T_B(Imm) \
  202. ((0xe000 | (Imm)) \
  203. | ((0xe000 | (Imm)) << 16))
  204. /* Breakpoint instruction (ARMv5) (Thumb state)
  205. * Im: 8-bit immediate
  206. */
  207. #define ARMV5_T_BKPT(Im) \
  208. ((0xbe00 | (Im)) \
  209. | ((0xbe00 | (Im)) << 16))
  210. /* Move to Register from Special Register
  211. * 32 bit Thumb2 instruction
  212. * Rd: destination register
  213. * SYSm: source special register
  214. */
  215. #define ARM_T2_MRS(Rd, SYSm) \
  216. ((0xF3EF) | ((0x8000 | (Rd << 8) | SYSm) << 16))
  217. /* Move from Register from Special Register
  218. * 32 bit Thumb2 instruction
  219. * Rd: source register
  220. * SYSm: destination special register
  221. */
  222. #define ARM_T2_MSR(SYSm, Rn) \
  223. ((0xF380 | (Rn << 8)) | ((0x8800 | SYSm) << 16))
  224. /* Change Processor State.
  225. * 16 bit Thumb2 instruction
  226. * Rd: source register
  227. * IF: A_FLAG and/or I_FLAG and/or F_FLAG
  228. */
  229. #define A_FLAG 4
  230. #define I_FLAG 2
  231. #define F_FLAG 1
  232. #define ARM_T2_CPSID(IF) \
  233. ((0xB660 | (1 << 8) | ((IF)&0x3)) \
  234. | ((0xB660 | (1 << 8) | ((IF)&0x3)) << 16))
  235. #define ARM_T2_CPSIE(IF) \
  236. ((0xB660 | (0 << 8) | ((IF)&0x3)) \
  237. | ((0xB660 | (0 << 8) | ((IF)&0x3)) << 16))
  238. #endif /* __ARM_OPCODES_H */