raavr.pas 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. {
  2. Copyright (c) 1998-2003 by Carl Eric Codere and Peter Vreman
  3. Handles the common arm assembler reader routines
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. unit raavr;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. cpubase,
  22. aasmtai,aasmdata,
  23. rautils,
  24. globtype;
  25. type
  26. TAVROperand=class(TOperand)
  27. end;
  28. TAVRInstruction=class(TInstruction)
  29. function ConcatInstruction(p:TAsmList) : tai;override;
  30. end;
  31. TRegType = (rt_all, rt_even, rt_16_31, rt_even_24_30, rt_16_23, rt_XYZ, rt_YZ, rt_X, rt_Y, rt_Z);
  32. TAVROpConstraint = record
  33. case typ : toptype of
  34. top_none : ();
  35. top_reg : (rt: TRegType; am: set of taddressmode; minconst, maxconst: tcgint);
  36. top_ref,
  37. top_const : (max, min: tcgint);
  38. end;
  39. // Constraints of operands per opcode
  40. // Encode variable number of operands by bit position, e.g.
  41. // 2 operands = 1 shl 2 = 4
  42. // 1 or 2 operands = 1 shl 1 + 1 shl 2 = 6
  43. TAVRInstrConstraint = record
  44. numOperands: byte;
  45. Operands: array[0..max_operands-1] of TAVROpConstraint;
  46. end;
  47. const
  48. AVRInstrConstraint: array[TAsmOp] of TAVRInstrConstraint =
  49. // A_NONE
  50. ((numOperands: 0; Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
  51. // A_ADD
  52. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
  53. // A_ADC
  54. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
  55. // A_ADIW
  56. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_even_24_30), (typ: top_const; max: 63; min: 0), (typ: top_none), (typ: top_none))),
  57. // A_SUB
  58. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
  59. // A_SUBI
  60. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_31), (typ: top_const; max: 255; min: -128), (typ: top_none), (typ: top_none))),
  61. // A_SBC
  62. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
  63. // A_SBCI
  64. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_31), (typ: top_const; max: 255; min: -128), (typ: top_none), (typ: top_none))),
  65. // A_SBRC
  66. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_const; max: 7; min: 0), (typ: top_none), (typ: top_none))),
  67. // A_SBRS
  68. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_const; max: 7; min: 0), (typ: top_none), (typ: top_none))),
  69. // A_SBIW
  70. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_even_24_30), (typ: top_const; max: 63; min: 0), (typ: top_none), (typ: top_none))),
  71. // A_AND
  72. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
  73. // A_ANDI
  74. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_31), (typ: top_const; max: 255; min: -128), (typ: top_none), (typ: top_none))),
  75. // A_OR
  76. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
  77. // A_ORI
  78. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_31), (typ: top_const; max: 255; min: -128), (typ: top_none), (typ: top_none))),
  79. // A_EOR
  80. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
  81. // A_COM
  82. (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none), (typ: top_none))),
  83. // A_NEG
  84. (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none), (typ: top_none))),
  85. // A_SBR
  86. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_31), (typ: top_const; max: 255; min: -128), (typ: top_none), (typ: top_none))),
  87. // A_CBR
  88. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_31), (typ: top_const; max: 255; min: -128), (typ: top_none), (typ: top_none))),
  89. // A_INC
  90. (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none), (typ: top_none))),
  91. // A_DEC
  92. (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none), (typ: top_none))),
  93. // A_TST
  94. (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none), (typ: top_none))),
  95. // A_MUL
  96. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
  97. // A_MULS
  98. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_31), (typ: top_reg; rt: rt_16_31), (typ: top_none), (typ: top_none))),
  99. // A_MULSU
  100. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_23), (typ: top_reg; rt: rt_16_23), (typ: top_none), (typ: top_none))),
  101. // A_FMUL
  102. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_23), (typ: top_reg; rt: rt_16_23), (typ: top_none), (typ: top_none))),
  103. // A_FMULS
  104. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_23), (typ: top_reg; rt: rt_16_23), (typ: top_none), (typ: top_none))),
  105. // A_FMULSU
  106. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_23), (typ: top_reg; rt: rt_16_23), (typ: top_none), (typ: top_none))),
  107. // A_RJMP
  108. (numOperands: (1 shl 1); Operands: ((typ: top_const; max: 2047; min: -2048), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
  109. // A_IJMP
  110. (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
  111. // A_EIJMP
  112. (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
  113. // A_JMP, max size depends on size op PC
  114. (numOperands: (1 shl 1); Operands: ((typ: top_const; max: (1 shl 22 - 1); min: 0), (typ: top_none), (typ: top_none), (typ: top_none))),
  115. // A_RCALL
  116. (numOperands: (1 shl 1); Operands: ((typ: top_const; max: 2047; min: -2048), (typ: top_none), (typ: top_none), (typ: top_none))),
  117. // A_ICALL
  118. (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
  119. // A_EICALL
  120. (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
  121. // A_CALL, max size depends on size op PC
  122. (numOperands: (1 shl 1); Operands: ((typ: top_const; max: (1 shl 22 - 1); min: 0), (typ: top_none), (typ: top_none), (typ: top_none))),
  123. // A_RET
  124. (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
  125. // A_IRET
  126. (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
  127. // A_CPSE
  128. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
  129. // A_CP
  130. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
  131. // A_CPC
  132. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
  133. // A_CPI
  134. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_31), (typ: top_const; max: 255; min: -128), (typ: top_none), (typ: top_none))),
  135. // A_SBIC
  136. (numOperands: (1 shl 2); Operands: ((typ: top_const; max: 31; min: 0), (typ: top_const; max: 7; min: 0), (typ: top_none), (typ: top_none))),
  137. // A_SBIS
  138. (numOperands: (1 shl 2); Operands: ((typ: top_const; max: 31; min: 0), (typ: top_const; max: 7; min: 0), (typ: top_none), (typ: top_none))),
  139. // A_BRxx
  140. (numOperands: (1 shl 1); Operands: ((typ: top_const; max: 63; min: -64), (typ: top_none), (typ: top_none), (typ: top_none))),
  141. // A_MOV
  142. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
  143. // A_MOVW
  144. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_even), (typ: top_reg; rt: rt_even), (typ: top_none), (typ: top_none))),
  145. // A_LDI
  146. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_31), (typ: top_const; max: 255; min: -128), (typ: top_none), (typ: top_none))),
  147. // A_LDS TODO: There are 2 versions with different machine codes and constant ranges. Could possibly distinguish based on size of PC?
  148. // Perhaps handle separately with a check on sub-architecture? Range check only important if smaller instruction code selected on larger arch
  149. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_const; max: 65535; min: 0), (typ: top_none), (typ: top_none))),
  150. // A_LD
  151. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_XYZ; am: [AM_UNCHANGED, AM_POSTINCREMENT, AM_PREDRECEMENT]), (typ: top_none), (typ: top_none))),
  152. // A_LDD
  153. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_YZ; am: [AM_UNCHANGED]; minconst: 0; maxconst: 63), (typ: top_none), (typ: top_none))),
  154. // A_STS TODO: See LDS above
  155. (numOperands: (1 shl 2); Operands: ((typ: top_const; max: 65535; min: 0), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
  156. // A_ST
  157. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_XYZ; am: [AM_UNCHANGED, AM_POSTINCREMENT, AM_PREDRECEMENT]), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
  158. // A_STD
  159. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_YZ; am: [AM_UNCHANGED]; minconst: 0; maxconst: 63), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
  160. // A_LPM
  161. (numOperands: (1 shl 0 + 1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_Z; am: [AM_UNCHANGED, AM_POSTINCREMENT]), (typ: top_none), (typ: top_none))),
  162. // A_ELPM
  163. (numOperands: (1 shl 0 + 1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_Z; am: [AM_UNCHANGED, AM_POSTINCREMENT]), (typ: top_none), (typ: top_none))),
  164. // A_SPM
  165. (numOperands: (1 shl 0 + 1 shl 1); Operands: ((typ: top_reg; rt: rt_Z; am: [AM_UNCHANGED, AM_POSTINCREMENT]), (typ: top_none), (typ: top_none), (typ: top_none))),
  166. // A_IN
  167. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_const; max: 63; min: 0), (typ: top_none), (typ: top_none))),
  168. // A_OUT
  169. (numOperands: (1 shl 2); Operands: ((typ: top_const; max: 63; min: 0), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
  170. // A_PUSH
  171. (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none), (typ: top_none))),
  172. // A_POP
  173. (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none), (typ: top_none))),
  174. // A_LSL
  175. (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none), (typ: top_none))),
  176. // A_LSR
  177. (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none), (typ: top_none))),
  178. // A_ROL
  179. (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none), (typ: top_none))),
  180. // A_ROR
  181. (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none), (typ: top_none))),
  182. // A_ASR
  183. (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none), (typ: top_none))),
  184. // A_SWAP
  185. (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none), (typ: top_none))),
  186. // A_BSET
  187. (numOperands: (1 shl 1); Operands: ((typ: top_const; max: 7; min: 0), (typ: top_none), (typ: top_none), (typ: top_none))),
  188. // A_BCLR
  189. (numOperands: (1 shl 1); Operands: ((typ: top_const; max: 7; min: 0), (typ: top_none), (typ: top_none), (typ: top_none))),
  190. // A_SBI
  191. (numOperands: (1 shl 2); Operands: ((typ: top_const; max: 32; min: 0), (typ: top_const; max: 7; min: 0), (typ: top_none), (typ: top_none))),
  192. // A_CBI
  193. (numOperands: (1 shl 2); Operands: ((typ: top_const; max: 32; min: 0), (typ: top_const; max: 7; min: 0), (typ: top_none), (typ: top_none))),
  194. // A_SEC
  195. (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
  196. // A_SEH
  197. (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
  198. // A_SEI
  199. (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
  200. // A_SEN
  201. (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
  202. // A_SER
  203. (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_16_31), (typ: top_none), (typ: top_none), (typ: top_none))),
  204. // A_SES
  205. (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
  206. // A_SET
  207. (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
  208. // A_SEV
  209. (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
  210. // A_SEZ
  211. (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
  212. // A_CLC
  213. (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
  214. // A_CLH
  215. (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
  216. // A_CLI
  217. (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
  218. // A_CLN
  219. (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
  220. // A_CLR
  221. (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none), (typ: top_none))),
  222. // A_CLS
  223. (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
  224. // A_CLT
  225. (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
  226. // A_CLV
  227. (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
  228. // A_CLZ
  229. (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
  230. // A_BST
  231. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_const; max: 7; min: 0), (typ: top_none), (typ: top_none))),
  232. // A_BLD
  233. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_const; max: 7; min: 0), (typ: top_none), (typ: top_none))),
  234. // A_BREAK
  235. (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
  236. // A_NOP
  237. (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
  238. // A_SLEEP
  239. (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
  240. // A_WDR
  241. (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
  242. // A_XCH
  243. (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_Z), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none)))
  244. );
  245. implementation
  246. uses
  247. aasmcpu, verbose, cgbase, itcpugas;
  248. function TAVRInstruction.ConcatInstruction(p:TAsmList) : tai;
  249. var
  250. i: integer;
  251. err, opregasref: boolean;
  252. s1, s2: string;
  253. reg: tregister;
  254. begin
  255. result:=inherited ConcatInstruction(p);
  256. if Result.typ = ait_instruction then
  257. begin
  258. // check if number of operands fall inside the allowed set
  259. if ((1 shl taicpu(Result).ops) and AVRInstrConstraint[opcode].numOperands = 0) then
  260. Message(asmr_e_invalid_opcode_and_operand)
  261. else
  262. begin
  263. for i := 0 to taicpu(Result).ops-1 do
  264. begin
  265. err := true;
  266. opregasref := false;
  267. // Type check
  268. if (taicpu(Result).oper[i]^.typ = AVRInstrConstraint[opcode].Operands[i].typ) then
  269. err := false
  270. // if label was specified check if const is expected
  271. else if (AVRInstrConstraint[opcode].Operands[i].typ = top_const) and (taicpu(Result).oper[i]^.typ = top_ref) then
  272. err := false
  273. // Also expressions such as X+, -Z and X+8 are classified as TOP_REF
  274. else if (AVRInstrConstraint[opcode].Operands[i].typ = top_reg) and (taicpu(Result).oper[i]^.typ = top_ref) and
  275. (int64(taicpu(Result).oper[i]^.ref^.base) and $01030000 > 0) then
  276. begin
  277. err := false;
  278. opregasref := true;
  279. reg := taicpu(Result).oper[i]^.ref^.base;
  280. end
  281. // LDD r1, a or STD a, r1 where a is local variable => type is set to top_local
  282. // also mov r10, TypeCastToByte(procParam) returns top_local for typecasted param
  283. // but no further information is available at this point to check
  284. else if (AVRInstrConstraint[opcode].Operands[i].typ = top_reg) and (taicpu(Result).oper[i]^.typ = top_local) and
  285. (opcode in [A_LDD, A_STD, A_MOV]) then
  286. begin
  287. err := false;
  288. end;
  289. if err then
  290. begin
  291. WriteStr(s1, taicpu(Result).oper[i]^.typ);
  292. WriteStr(s2, AVRInstrConstraint[opcode].Operands[i].typ);
  293. Message2(type_e_incompatible_types, s1, s2);
  294. end
  295. else if (taicpu(Result).oper[i]^.typ = top_reg) or opregasref then
  296. begin
  297. err := false;
  298. if not opregasref then
  299. reg := taicpu(Result).oper[i]^.reg;
  300. case AVRInstrConstraint[opcode].Operands[i].rt of
  301. rt_all: err := int64(reg) > $1030000; // excluding pointer registers X, Y, Z
  302. rt_even: err := int64(reg) mod 2 = 1;
  303. rt_even_24_30: err := not(word(reg) in [24, 26, 28, 30]);
  304. rt_16_31: err := not(word(reg) in [16..31]);
  305. rt_16_23: err := not(word(reg) in [16..23]);
  306. rt_Z: err := (int64(reg) <> $0103001e);
  307. rt_YZ: err := not((int64(reg) = $0103001c) or
  308. (int64(reg) =$0103001e));
  309. rt_XYZ: err := not((int64(reg) = $0103001a) or
  310. (int64(reg) = $0103001c) or
  311. (int64(reg) = $0103001e));
  312. end;
  313. // Catch erroneous z if it should be z+k or something similar
  314. // By checking if .am is not empty (implying a reference is expected)
  315. // ldd R20, z should not pass => opregasref = true
  316. // but ldd R20, z+1 should pass => opregasref = false
  317. if not (err) and (AVRInstrConstraint[opcode].Operands[i].am = [AM_UNCHANGED]) then
  318. err := not opregasref;
  319. if not (err) and not(AM_UNCHANGED in AVRInstrConstraint[opcode].Operands[i].am) and
  320. ((AM_POSTINCREMENT in AVRInstrConstraint[opcode].Operands[i].am) or
  321. (AM_PREDRECEMENT in AVRInstrConstraint[opcode].Operands[i].am)) then
  322. err := not opregasref;
  323. if not(err) and opregasref then
  324. begin
  325. if (taicpu(Result).oper[i]^.ref^.addressmode = AM_UNCHANGED) and
  326. (AM_UNCHANGED in AVRInstrConstraint[opcode].Operands[i].am) then
  327. err := ((taicpu(Result).oper[i]^.ref^.offset > AVRInstrConstraint[opcode].Operands[i].maxconst) or
  328. (taicpu(Result).oper[i]^.ref^.offset < AVRInstrConstraint[opcode].Operands[i].minconst))
  329. else if (taicpu(Result).oper[i]^.ref^.addressmode in AVRInstrConstraint[opcode].Operands[i].am) then
  330. err := false
  331. else
  332. err := true;
  333. end;
  334. if err then
  335. Message1(asmr_e_invalid_ref_register, gas_regname(reg));
  336. end
  337. else if taicpu(Result).oper[i]^.typ = top_const then
  338. begin
  339. // Need to check if original value was signed or simply sign overflowed in 16 bit?
  340. if ((taicpu(Result).oper[i]^.val > AVRInstrConstraint[opcode].Operands[i].max) or
  341. (taicpu(Result).oper[i]^.val < AVRInstrConstraint[opcode].Operands[i].min)) then
  342. Message(asmr_e_constant_out_of_bounds);
  343. end;
  344. end;
  345. end;
  346. end;
  347. end;
  348. end.