0044-RISC-V-Add-sext.-bh-and-zext.-bhw-pseudo-instruction.patch 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. From 16266fab77ff6e3760a08f107c782b91e595b33e Mon Sep 17 00:00:00 2001
  2. From: Nelson Chu <nelson.chu@sifive.com>
  3. Date: Wed, 9 Dec 2020 13:53:22 +0800
  4. Subject: [PATCH 44/48] RISC-V: Add sext.[bh] and zext.[bhw] pseudo
  5. instructions.
  6. https://github.com/riscv/riscv-asm-manual/pull/61
  7. We aleady have sext.w, so just add sext.b, sext.h, zext.b, zext.h
  8. and zext.w. In a certain sense, zext.b is not a pseudo - It is an
  9. alias of andi. Similarly, sext.b and sext.h are aliases of other
  10. rvb instructions, when we enable b extension; But they are pseudos
  11. when we just enable rvi. However, this patch does not consider the
  12. rvb cases. Besides, zext.w is only valid in rv64.
  13. gas/
  14. * config/tc-riscv.c (riscv_ext): New function. Use md_assemblef
  15. to expand the zext and sext pseudos, to give them a chance to be
  16. expanded into c-ext instructions.
  17. (macro): Handle M_ZEXTH, M_ZEXTW, M_SEXTB and M_SEXTH.
  18. * testsuite/gas/riscv/ext.s: New testcase.
  19. * testsuite/gas/riscv/ext-32.d: Likewise.
  20. * testsuite/gas/riscv/ext-64.d: Likewise.
  21. include/
  22. * opcode/riscv.h (M_ZEXTH, M_ZEXTW, M_SEXTB, M_SEXTH.): Added.
  23. opcodes/
  24. * riscv-opc.c (riscv_opcodes): Add sext.[bh] and zext.[bhw].
  25. ---
  26. gas/config/tc-riscv.c | 33 +++++++++++++++++++++
  27. gas/testsuite/gas/riscv/ext-32.d | 39 ++++++++++++++++++++++++
  28. gas/testsuite/gas/riscv/ext-64.d | 51 ++++++++++++++++++++++++++++++++
  29. gas/testsuite/gas/riscv/ext.s | 38 ++++++++++++++++++++++++
  30. include/opcode/riscv.h | 4 +++
  31. opcodes/riscv-opc.c | 5 ++++
  32. 6 files changed, 170 insertions(+)
  33. create mode 100644 gas/testsuite/gas/riscv/ext-32.d
  34. create mode 100644 gas/testsuite/gas/riscv/ext-64.d
  35. create mode 100644 gas/testsuite/gas/riscv/ext.s
  36. diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
  37. index 2a5ac9c861..bee1186c3a 100644
  38. --- a/gas/config/tc-riscv.c
  39. +++ b/gas/config/tc-riscv.c
  40. @@ -1623,6 +1623,23 @@ vector_macro (struct riscv_cl_insn *ip)
  41. }
  42. }
  43. +/* Zero extend and sign extend byte/half-word/word. */
  44. +
  45. +static void
  46. +riscv_ext (int destreg, int srcreg, unsigned shift, bfd_boolean sign)
  47. +{
  48. + if (sign)
  49. + {
  50. + md_assemblef ("slli x%d, x%d, 0x%x", destreg, srcreg, shift);
  51. + md_assemblef ("srai x%d, x%d, 0x%x", destreg, destreg, shift);
  52. + }
  53. + else
  54. + {
  55. + md_assemblef ("slli x%d, x%d, 0x%x", destreg, srcreg, shift);
  56. + md_assemblef ("srli x%d, x%d, 0x%x", destreg, destreg, shift);
  57. + }
  58. +}
  59. +
  60. /* Expand RISC-V assembly macros into one or more instructions. */
  61. static void
  62. macro (struct riscv_cl_insn *ip, expressionS *imm_expr,
  63. @@ -1769,6 +1786,22 @@ macro (struct riscv_cl_insn *ip, expressionS *imm_expr,
  64. vector_macro (ip);
  65. break;
  66. + case M_ZEXTH:
  67. + riscv_ext (rd, rs1, xlen - 16, FALSE);
  68. + break;
  69. +
  70. + case M_ZEXTW:
  71. + riscv_ext (rd, rs1, xlen - 32, FALSE);
  72. + break;
  73. +
  74. + case M_SEXTB:
  75. + riscv_ext (rd, rs1, xlen - 8, TRUE);
  76. + break;
  77. +
  78. + case M_SEXTH:
  79. + riscv_ext (rd, rs1, xlen - 16, TRUE);
  80. + break;
  81. +
  82. default:
  83. as_bad (_("Macro %s not implemented"), ip->insn_mo->name);
  84. break;
  85. diff --git a/gas/testsuite/gas/riscv/ext-32.d b/gas/testsuite/gas/riscv/ext-32.d
  86. new file mode 100644
  87. index 0000000000..918c9c8a16
  88. --- /dev/null
  89. +++ b/gas/testsuite/gas/riscv/ext-32.d
  90. @@ -0,0 +1,39 @@
  91. +#as: -march=rv32i
  92. +#source: ext.s
  93. +#objdump: -d
  94. +
  95. +.*:[ ]+file format .*
  96. +
  97. +
  98. +Disassembly of section .text:
  99. +
  100. +0+000 <target>:
  101. +[ ]+0:[ ]+0ff57513[ ]+zext.b[ ]+a0,a0
  102. +[ ]+4:[ ]+01051513[ ]+slli[ ]+a0,a0,0x10
  103. +[ ]+8:[ ]+01055513[ ]+srli[ ]+a0,a0,0x10
  104. +[ ]+c:[ ]+01851513[ ]+slli[ ]+a0,a0,0x18
  105. +[ ]+10:[ ]+41855513[ ]+srai[ ]+a0,a0,0x18
  106. +[ ]+14:[ ]+01051513[ ]+slli[ ]+a0,a0,0x10
  107. +[ ]+18:[ ]+41055513[ ]+srai[ ]+a0,a0,0x10
  108. +[ ]+1c:[ ]+0ff67593[ ]+zext.b[ ]+a1,a2
  109. +[ ]+20:[ ]+01061593[ ]+slli[ ]+a1,a2,0x10
  110. +[ ]+24:[ ]+0105d593[ ]+srli[ ]+a1,a1,0x10
  111. +[ ]+28:[ ]+01861593[ ]+slli[ ]+a1,a2,0x18
  112. +[ ]+2c:[ ]+4185d593[ ]+srai[ ]+a1,a1,0x18
  113. +[ ]+30:[ ]+01061593[ ]+slli[ ]+a1,a2,0x10
  114. +[ ]+34:[ ]+4105d593[ ]+srai[ ]+a1,a1,0x10
  115. +[ ]+38:[ ]+0ff57513[ ]+zext.b[ ]+a0,a0
  116. +[ ]+3c:[ ]+0542[ ]+slli[ ]+a0,a0,0x10
  117. +[ ]+3e:[ ]+8141[ ]+srli[ ]+a0,a0,0x10
  118. +[ ]+40:[ ]+0562[ ]+slli[ ]+a0,a0,0x18
  119. +[ ]+42:[ ]+8561[ ]+srai[ ]+a0,a0,0x18
  120. +[ ]+44:[ ]+0542[ ]+slli[ ]+a0,a0,0x10
  121. +[ ]+46:[ ]+8541[ ]+srai[ ]+a0,a0,0x10
  122. +[ ]+48:[ ]+0ff67593[ ]+zext.b[ ]+a1,a2
  123. +[ ]+4c:[ ]+01061593[ ]+slli[ ]+a1,a2,0x10
  124. +[ ]+50:[ ]+81c1[ ]+srli[ ]+a1,a1,0x10
  125. +[ ]+52:[ ]+01861593[ ]+slli[ ]+a1,a2,0x18
  126. +[ ]+56:[ ]+85e1[ ]+srai[ ]+a1,a1,0x18
  127. +[ ]+58:[ ]+01061593[ ]+slli[ ]+a1,a2,0x10
  128. +[ ]+5c:[ ]+85c1[ ]+srai[ ]+a1,a1,0x10
  129. +#...
  130. diff --git a/gas/testsuite/gas/riscv/ext-64.d b/gas/testsuite/gas/riscv/ext-64.d
  131. new file mode 100644
  132. index 0000000000..49d109b1db
  133. --- /dev/null
  134. +++ b/gas/testsuite/gas/riscv/ext-64.d
  135. @@ -0,0 +1,51 @@
  136. +#as: -march=rv64i -defsym __64_bit__=1
  137. +#source: ext.s
  138. +#objdump: -d
  139. +
  140. +.*:[ ]+file format .*
  141. +
  142. +
  143. +Disassembly of section .text:
  144. +
  145. +0+000 <target>:
  146. +[ ]+0:[ ]+0ff57513[ ]+zext.b[ ]+a0,a0
  147. +[ ]+4:[ ]+03051513[ ]+slli[ ]+a0,a0,0x30
  148. +[ ]+8:[ ]+03055513[ ]+srli[ ]+a0,a0,0x30
  149. +[ ]+c:[ ]+03851513[ ]+slli[ ]+a0,a0,0x38
  150. +[ ]+10:[ ]+43855513[ ]+srai[ ]+a0,a0,0x38
  151. +[ ]+14:[ ]+03051513[ ]+slli[ ]+a0,a0,0x30
  152. +[ ]+18:[ ]+43055513[ ]+srai[ ]+a0,a0,0x30
  153. +[ ]+1c:[ ]+0ff67593[ ]+zext.b[ ]+a1,a2
  154. +[ ]+20:[ ]+03061593[ ]+slli[ ]+a1,a2,0x30
  155. +[ ]+24:[ ]+0305d593[ ]+srli[ ]+a1,a1,0x30
  156. +[ ]+28:[ ]+03861593[ ]+slli[ ]+a1,a2,0x38
  157. +[ ]+2c:[ ]+4385d593[ ]+srai[ ]+a1,a1,0x38
  158. +[ ]+30:[ ]+03061593[ ]+slli[ ]+a1,a2,0x30
  159. +[ ]+34:[ ]+4305d593[ ]+srai[ ]+a1,a1,0x30
  160. +[ ]+38:[ ]+02051513[ ]+slli[ ]+a0,a0,0x20
  161. +[ ]+3c:[ ]+02055513[ ]+srli[ ]+a0,a0,0x20
  162. +[ ]+40:[ ]+0005051b[ ]+sext.w[ ]+a0,a0
  163. +[ ]+44:[ ]+02061593[ ]+slli[ ]+a1,a2,0x20
  164. +[ ]+48:[ ]+0205d593[ ]+srli[ ]+a1,a1,0x20
  165. +[ ]+4c:[ ]+0006059b[ ]+sext.w[ ]+a1,a2
  166. +[ ]+50:[ ]+0ff57513[ ]+zext.b[ ]+a0,a0
  167. +[ ]+54:[ ]+1542[ ]+slli[ ]+a0,a0,0x30
  168. +[ ]+56:[ ]+9141[ ]+srli[ ]+a0,a0,0x30
  169. +[ ]+58:[ ]+1562[ ]+slli[ ]+a0,a0,0x38
  170. +[ ]+5a:[ ]+9561[ ]+srai[ ]+a0,a0,0x38
  171. +[ ]+5c:[ ]+1542[ ]+slli[ ]+a0,a0,0x30
  172. +[ ]+5e:[ ]+9541[ ]+srai[ ]+a0,a0,0x30
  173. +[ ]+60:[ ]+0ff67593[ ]+zext.b[ ]+a1,a2
  174. +[ ]+64:[ ]+03061593[ ]+slli[ ]+a1,a2,0x30
  175. +[ ]+68:[ ]+91c1[ ]+srli[ ]+a1,a1,0x30
  176. +[ ]+6a:[ ]+03861593[ ]+slli[ ]+a1,a2,0x38
  177. +[ ]+6e:[ ]+95e1[ ]+srai[ ]+a1,a1,0x38
  178. +[ ]+70:[ ]+03061593[ ]+slli[ ]+a1,a2,0x30
  179. +[ ]+74:[ ]+95c1[ ]+srai[ ]+a1,a1,0x30
  180. +[ ]+76:[ ]+1502[ ]+slli[ ]+a0,a0,0x20
  181. +[ ]+78:[ ]+9101[ ]+srli[ ]+a0,a0,0x20
  182. +[ ]+7a:[ ]+2501[ ]+sext.w[ ]+a0,a0
  183. +[ ]+7c:[ ]+02061593[ ]+slli[ ]+a1,a2,0x20
  184. +[ ]+80:[ ]+9181[ ]+srli[ ]+a1,a1,0x20
  185. +[ ]+82:[ ]+0006059b[ ]+sext.w[ ]+a1,a2
  186. +#...
  187. diff --git a/gas/testsuite/gas/riscv/ext.s b/gas/testsuite/gas/riscv/ext.s
  188. new file mode 100644
  189. index 0000000000..f95713422a
  190. --- /dev/null
  191. +++ b/gas/testsuite/gas/riscv/ext.s
  192. @@ -0,0 +1,38 @@
  193. +target:
  194. + .option norvc
  195. + zext.b a0, a0
  196. + zext.h a0, a0
  197. + sext.b a0, a0
  198. + sext.h a0, a0
  199. +
  200. + zext.b a1, a2
  201. + zext.h a1, a2
  202. + sext.b a1, a2
  203. + sext.h a1, a2
  204. +
  205. +.ifdef __64_bit__
  206. + zext.w a0, a0
  207. + sext.w a0, a0
  208. +
  209. + zext.w a1, a2
  210. + sext.w a1, a2
  211. +.endif
  212. +
  213. + .option rvc
  214. + zext.b a0, a0
  215. + zext.h a0, a0
  216. + sext.b a0, a0
  217. + sext.h a0, a0
  218. +
  219. + zext.b a1, a2
  220. + zext.h a1, a2
  221. + sext.b a1, a2
  222. + sext.h a1, a2
  223. +
  224. +.ifdef __64_bit__
  225. + zext.w a0, a0
  226. + sext.w a0, a0
  227. +
  228. + zext.w a1, a2
  229. + sext.w a1, a2
  230. +.endif
  231. diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
  232. index 9af4f6514c..71498563c3 100644
  233. --- a/include/opcode/riscv.h
  234. +++ b/include/opcode/riscv.h
  235. @@ -583,6 +583,10 @@ enum
  236. M_VMSGEU,
  237. M_RL,
  238. M_FL,
  239. + M_ZEXTH,
  240. + M_ZEXTW,
  241. + M_SEXTB,
  242. + M_SEXTH,
  243. M_NUM_MACROS
  244. };
  245. diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
  246. index 5d49912e2e..5f0885b5c6 100644
  247. --- a/opcodes/riscv-opc.c
  248. +++ b/opcodes/riscv-opc.c
  249. @@ -705,6 +705,7 @@ const struct riscv_opcode riscv_opcodes[] =
  250. {"mv", 0, INSN_CLASS_I, "d,s", MATCH_ADDI, MASK_ADDI | MASK_IMM, match_opcode, INSN_ALIAS },
  251. {"move", 0, INSN_CLASS_C, "d,CV", MATCH_C_MV, MASK_C_MV, match_c_add, INSN_ALIAS },
  252. {"move", 0, INSN_CLASS_I, "d,s", MATCH_ADDI, MASK_ADDI | MASK_IMM, match_opcode, INSN_ALIAS },
  253. +{"zext.b", 0, INSN_CLASS_I, "d,s", MATCH_ANDI | ENCODE_ITYPE_IMM (255), MASK_ANDI | MASK_IMM, match_opcode, INSN_ALIAS },
  254. {"andi", 0, INSN_CLASS_C, "Cs,Cw,Co", MATCH_C_ANDI, MASK_C_ANDI, match_opcode, INSN_ALIAS },
  255. {"andi", 0, INSN_CLASS_I, "d,s,j", MATCH_ANDI, MASK_ANDI, match_opcode, 0 },
  256. {"and", 0, INSN_CLASS_C, "Cs,Cw,Ct", MATCH_C_AND, MASK_C_AND, match_opcode, INSN_ALIAS },
  257. @@ -1162,6 +1163,7 @@ const struct riscv_opcode riscv_opcodes[] =
  258. {"sh3add", 0, INSN_CLASS_B_OR_ZBA, "d,s,t", MATCH_SH3ADD, MASK_SH3ADD, match_opcode, 0 },
  259. {"slliu.w", 64, INSN_CLASS_B_OR_ZBA, "d,s,>", MATCH_SLLIU_W, MASK_SLLIU_W, match_opcode, 0 },
  260. {"zext.w", 64, INSN_CLASS_B_OR_ZBA_OR_ZBB, "d,s", MATCH_ADDU_W, MASK_ADDU_W | MASK_RS2, match_opcode, INSN_ALIAS },
  261. +{"zext.w", 64, INSN_CLASS_I, "d,s", 0, (int) M_ZEXTW, match_never, INSN_MACRO },
  262. {"addu.w", 64, INSN_CLASS_B_OR_ZBA, "d,s,t", MATCH_ADDU_W, MASK_ADDU_W, match_opcode, 0 },
  263. {"sh1addu.w",64, INSN_CLASS_B_OR_ZBA, "d,s,t", MATCH_SH1ADDU_W, MASK_SH1ADDU_W, match_opcode, 0 },
  264. {"sh2addu.w",64, INSN_CLASS_B_OR_ZBA, "d,s,t", MATCH_SH2ADDU_W, MASK_SH2ADDU_W, match_opcode, 0 },
  265. @@ -1184,9 +1186,12 @@ const struct riscv_opcode riscv_opcodes[] =
  266. {"ror", 0, INSN_CLASS_B_OR_ZBB, "d,s,t", MATCH_ROR, MASK_ROR, match_opcode, 0 },
  267. {"ror", 0, INSN_CLASS_B_OR_ZBB, "d,s,>", MATCH_RORI, MASK_RORI, match_opcode, INSN_ALIAS },
  268. {"sext.b", 0, INSN_CLASS_B_OR_ZBB, "d,s", MATCH_SEXT_B, MASK_SEXT_B, match_opcode, 0 },
  269. +{"sext.b", 0, INSN_CLASS_I, "d,s", 0, (int) M_SEXTB, match_never, INSN_MACRO },
  270. {"sext.h", 0, INSN_CLASS_B_OR_ZBB, "d,s", MATCH_SEXT_H, MASK_SEXT_H, match_opcode, 0 },
  271. +{"sext.h", 0, INSN_CLASS_I, "d,s", 0, (int) M_SEXTH, match_never, INSN_MACRO },
  272. {"zext.h", 32, INSN_CLASS_B_OR_ZBB, "d,s", MATCH_PACK, MASK_PACK | MASK_RS2, match_opcode, INSN_ALIAS }, /* pack with rs2=x0 */
  273. {"zext.h", 64, INSN_CLASS_B_OR_ZBB, "d,s", MATCH_PACKW, MASK_PACKW | MASK_RS2, match_opcode, INSN_ALIAS }, /* packw with rs2=x0 */
  274. +{"zext.h", 0, INSN_CLASS_I, "d,s", 0, (int) M_ZEXTH, match_never, INSN_MACRO },
  275. {"clzw", 64, INSN_CLASS_B_OR_ZBB, "d,s", MATCH_CLZW, MASK_CLZW, match_opcode, 0 },
  276. {"ctzw", 64, INSN_CLASS_B_OR_ZBB, "d,s", MATCH_CTZW, MASK_CTZW, match_opcode, 0 },
  277. {"pcntw", 64, INSN_CLASS_B_OR_ZBB, "d,s", MATCH_PCNTW, MASK_PCNTW, match_opcode, 0 },
  278. --
  279. 2.33.0