emit_glasm_floating_point.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. // Copyright 2021 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <string_view>
  5. #include "shader_recompiler/backend/glasm/emit_context.h"
  6. #include "shader_recompiler/backend/glasm/emit_glasm_instructions.h"
  7. #include "shader_recompiler/frontend/ir/value.h"
  8. namespace Shader::Backend::GLASM {
  9. template <typename InputType>
  10. static void Compare(EmitContext& ctx, IR::Inst& inst, InputType lhs, InputType rhs,
  11. std::string_view op, std::string_view type, bool ordered,
  12. bool inequality = false) {
  13. const Register ret{ctx.reg_alloc.Define(inst)};
  14. ctx.Add("{}.{} RC.x,{},{};", op, type, lhs, rhs);
  15. if (ordered && inequality) {
  16. ctx.Add("SEQ.{} RC.y,{},{};"
  17. "SEQ.{} RC.z,{},{};"
  18. "AND.U RC.x,RC.x,RC.y;"
  19. "AND.U RC.x,RC.x,RC.z;"
  20. "SNE.S {}.x,RC.x,0;",
  21. type, lhs, lhs, type, rhs, rhs, ret);
  22. } else if (ordered) {
  23. ctx.Add("SNE.S {}.x,RC.x,0;", ret);
  24. } else {
  25. ctx.Add("SNE.{} RC.y,{},{};"
  26. "SNE.{} RC.z,{},{};"
  27. "OR.U RC.x,RC.x,RC.y;"
  28. "OR.U RC.x,RC.x,RC.z;"
  29. "SNE.S {}.x,RC.x,0;",
  30. type, lhs, lhs, type, rhs, rhs, ret);
  31. }
  32. }
  33. void EmitFPAbs16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst,
  34. [[maybe_unused]] Register value) {
  35. throw NotImplementedException("GLASM instruction");
  36. }
  37. void EmitFPAbs32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value) {
  38. ctx.Add("MOV.F {}.x,|{}|;", inst, value);
  39. }
  40. void EmitFPAbs64(EmitContext& ctx, IR::Inst& inst, ScalarF64 value) {
  41. ctx.LongAdd("MOV.F64 {}.x,|{}|;", inst, value);
  42. }
  43. void EmitFPAdd16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst,
  44. [[maybe_unused]] Register a, [[maybe_unused]] Register b) {
  45. throw NotImplementedException("GLASM instruction");
  46. }
  47. void EmitFPAdd32(EmitContext& ctx, IR::Inst& inst, ScalarF32 a, ScalarF32 b) {
  48. ctx.Add("ADD.F {}.x,{},{};", inst, a, b);
  49. }
  50. void EmitFPAdd64(EmitContext& ctx, IR::Inst& inst, ScalarF64 a, ScalarF64 b) {
  51. ctx.LongAdd("ADD.F64 {}.x,{},{};", inst, a, b);
  52. }
  53. void EmitFPFma16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst,
  54. [[maybe_unused]] Register a, [[maybe_unused]] Register b,
  55. [[maybe_unused]] Register c) {
  56. throw NotImplementedException("GLASM instruction");
  57. }
  58. void EmitFPFma32(EmitContext& ctx, IR::Inst& inst, ScalarF32 a, ScalarF32 b, ScalarF32 c) {
  59. ctx.Add("MAD.F {}.x,{},{},{};", inst, a, b, c);
  60. }
  61. void EmitFPFma64(EmitContext& ctx, IR::Inst& inst, ScalarF64 a, ScalarF64 b, ScalarF64 c) {
  62. ctx.LongAdd("MAD.F64 {}.x,{},{},{};", inst, a, b, c);
  63. }
  64. void EmitFPMax32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] ScalarF32 a,
  65. [[maybe_unused]] ScalarF32 b) {
  66. throw NotImplementedException("GLASM instruction");
  67. }
  68. void EmitFPMax64(EmitContext& ctx, IR::Inst& inst, ScalarF64 a, ScalarF64 b) {
  69. ctx.LongAdd("MAX.F64 {},{},{};", inst, a, b);
  70. }
  71. void EmitFPMin32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] ScalarF32 a,
  72. [[maybe_unused]] ScalarF32 b) {
  73. throw NotImplementedException("GLASM instruction");
  74. }
  75. void EmitFPMin64(EmitContext& ctx, IR::Inst& inst, ScalarF64 a, ScalarF64 b) {
  76. ctx.LongAdd("MIN.F64 {},{},{};", inst, a, b);
  77. }
  78. void EmitFPMul16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst,
  79. [[maybe_unused]] Register a, [[maybe_unused]] Register b) {
  80. throw NotImplementedException("GLASM instruction");
  81. }
  82. void EmitFPMul32(EmitContext& ctx, IR::Inst& inst, ScalarF32 a, ScalarF32 b) {
  83. ctx.Add("MUL.F {}.x,{},{};", inst, a, b);
  84. }
  85. void EmitFPMul64(EmitContext& ctx, IR::Inst& inst, ScalarF64 a, ScalarF64 b) {
  86. ctx.LongAdd("MUL.F64 {}.x,{},{};", inst, a, b);
  87. }
  88. void EmitFPNeg16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) {
  89. throw NotImplementedException("GLASM instruction");
  90. }
  91. void EmitFPNeg32(EmitContext& ctx, IR::Inst& inst, ScalarRegister value) {
  92. ctx.Add("MOV.F {}.x,-{};", inst, value);
  93. }
  94. void EmitFPNeg64(EmitContext& ctx, IR::Inst& inst, Register value) {
  95. ctx.LongAdd("MOV.F64 {}.x,-{};", inst, value);
  96. }
  97. void EmitFPSin([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] ScalarF32 value) {
  98. throw NotImplementedException("GLASM instruction");
  99. }
  100. void EmitFPCos([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] ScalarF32 value) {
  101. throw NotImplementedException("GLASM instruction");
  102. }
  103. void EmitFPExp2([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] ScalarF32 value) {
  104. throw NotImplementedException("GLASM instruction");
  105. }
  106. void EmitFPLog2([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] ScalarF32 value) {
  107. throw NotImplementedException("GLASM instruction");
  108. }
  109. void EmitFPRecip32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] ScalarF32 value) {
  110. throw NotImplementedException("GLASM instruction");
  111. }
  112. void EmitFPRecip64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) {
  113. throw NotImplementedException("GLASM instruction");
  114. }
  115. void EmitFPRecipSqrt32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] ScalarF32 value) {
  116. throw NotImplementedException("GLASM instruction");
  117. }
  118. void EmitFPRecipSqrt64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) {
  119. throw NotImplementedException("GLASM instruction");
  120. }
  121. void EmitFPSqrt([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] ScalarF32 value) {
  122. throw NotImplementedException("GLASM instruction");
  123. }
  124. void EmitFPSaturate16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) {
  125. throw NotImplementedException("GLASM instruction");
  126. }
  127. void EmitFPSaturate32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value) {
  128. ctx.Add("MOV.F.SAT {}.x,{};", inst, value);
  129. }
  130. void EmitFPSaturate64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) {
  131. throw NotImplementedException("GLASM instruction");
  132. }
  133. void EmitFPClamp16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value,
  134. [[maybe_unused]] Register min_value, [[maybe_unused]] Register max_value) {
  135. throw NotImplementedException("GLASM instruction");
  136. }
  137. void EmitFPClamp32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] ScalarF32 value,
  138. [[maybe_unused]] ScalarF32 min_value, [[maybe_unused]] ScalarF32 max_value) {
  139. throw NotImplementedException("GLASM instruction");
  140. }
  141. void EmitFPClamp64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value,
  142. [[maybe_unused]] Register min_value, [[maybe_unused]] Register max_value) {
  143. throw NotImplementedException("GLASM instruction");
  144. }
  145. void EmitFPRoundEven16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) {
  146. throw NotImplementedException("GLASM instruction");
  147. }
  148. void EmitFPRoundEven32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] ScalarF32 value) {
  149. throw NotImplementedException("GLASM instruction");
  150. }
  151. void EmitFPRoundEven64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) {
  152. throw NotImplementedException("GLASM instruction");
  153. }
  154. void EmitFPFloor16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) {
  155. throw NotImplementedException("GLASM instruction");
  156. }
  157. void EmitFPFloor32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] ScalarF32 value) {
  158. throw NotImplementedException("GLASM instruction");
  159. }
  160. void EmitFPFloor64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) {
  161. throw NotImplementedException("GLASM instruction");
  162. }
  163. void EmitFPCeil16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) {
  164. throw NotImplementedException("GLASM instruction");
  165. }
  166. void EmitFPCeil32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] ScalarF32 value) {
  167. throw NotImplementedException("GLASM instruction");
  168. }
  169. void EmitFPCeil64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) {
  170. throw NotImplementedException("GLASM instruction");
  171. }
  172. void EmitFPTrunc16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) {
  173. throw NotImplementedException("GLASM instruction");
  174. }
  175. void EmitFPTrunc32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] ScalarF32 value) {
  176. throw NotImplementedException("GLASM instruction");
  177. }
  178. void EmitFPTrunc64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) {
  179. throw NotImplementedException("GLASM instruction");
  180. }
  181. void EmitFPOrdEqual16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register lhs,
  182. [[maybe_unused]] Register rhs) {
  183. throw NotImplementedException("GLASM instruction");
  184. }
  185. void EmitFPOrdEqual32(EmitContext& ctx, IR::Inst& inst, ScalarF32 lhs, ScalarF32 rhs) {
  186. Compare(ctx, inst, lhs, rhs, "SEQ", "F", true);
  187. }
  188. void EmitFPOrdEqual64(EmitContext& ctx, IR::Inst& inst, ScalarF64 lhs, ScalarF64 rhs) {
  189. Compare(ctx, inst, lhs, rhs, "SEQ", "F64", true);
  190. }
  191. void EmitFPUnordEqual16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register lhs,
  192. [[maybe_unused]] Register rhs) {
  193. throw NotImplementedException("GLASM instruction");
  194. }
  195. void EmitFPUnordEqual32(EmitContext& ctx, IR::Inst& inst, ScalarF32 lhs, ScalarF32 rhs) {
  196. Compare(ctx, inst, lhs, rhs, "SEQ", "F", false);
  197. }
  198. void EmitFPUnordEqual64(EmitContext& ctx, IR::Inst& inst, ScalarF64 lhs, ScalarF64 rhs) {
  199. Compare(ctx, inst, lhs, rhs, "SEQ", "F64", false);
  200. }
  201. void EmitFPOrdNotEqual16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register lhs,
  202. [[maybe_unused]] Register rhs) {
  203. throw NotImplementedException("GLASM instruction");
  204. }
  205. void EmitFPOrdNotEqual32(EmitContext& ctx, IR::Inst& inst, ScalarF32 lhs, ScalarF32 rhs) {
  206. Compare(ctx, inst, lhs, rhs, "SNE", "F", true, true);
  207. }
  208. void EmitFPOrdNotEqual64(EmitContext& ctx, IR::Inst& inst, ScalarF64 lhs, ScalarF64 rhs) {
  209. Compare(ctx, inst, lhs, rhs, "SNE", "F64", true, true);
  210. }
  211. void EmitFPUnordNotEqual16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register lhs,
  212. [[maybe_unused]] Register rhs) {
  213. throw NotImplementedException("GLASM instruction");
  214. }
  215. void EmitFPUnordNotEqual32(EmitContext& ctx, IR::Inst& inst, ScalarF32 lhs, ScalarF32 rhs) {
  216. Compare(ctx, inst, lhs, rhs, "SNE", "F", false, true);
  217. }
  218. void EmitFPUnordNotEqual64(EmitContext& ctx, IR::Inst& inst, ScalarF64 lhs, ScalarF64 rhs) {
  219. Compare(ctx, inst, lhs, rhs, "SNE", "F64", false, true);
  220. }
  221. void EmitFPOrdLessThan16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register lhs,
  222. [[maybe_unused]] Register rhs) {
  223. throw NotImplementedException("GLASM instruction");
  224. }
  225. void EmitFPOrdLessThan32(EmitContext& ctx, IR::Inst& inst, ScalarF32 lhs, ScalarF32 rhs) {
  226. Compare(ctx, inst, lhs, rhs, "SLT", "F", true);
  227. }
  228. void EmitFPOrdLessThan64(EmitContext& ctx, IR::Inst& inst, ScalarF64 lhs, ScalarF64 rhs) {
  229. Compare(ctx, inst, lhs, rhs, "SLT", "F64", true);
  230. }
  231. void EmitFPUnordLessThan16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register lhs,
  232. [[maybe_unused]] Register rhs) {
  233. throw NotImplementedException("GLASM instruction");
  234. }
  235. void EmitFPUnordLessThan32(EmitContext& ctx, IR::Inst& inst, ScalarF32 lhs, ScalarF32 rhs) {
  236. Compare(ctx, inst, lhs, rhs, "SLT", "F", false);
  237. }
  238. void EmitFPUnordLessThan64(EmitContext& ctx, IR::Inst& inst, ScalarF64 lhs, ScalarF64 rhs) {
  239. Compare(ctx, inst, lhs, rhs, "SLT", "F64", false);
  240. }
  241. void EmitFPOrdGreaterThan16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register lhs,
  242. [[maybe_unused]] Register rhs) {
  243. throw NotImplementedException("GLASM instruction");
  244. }
  245. void EmitFPOrdGreaterThan32(EmitContext& ctx, IR::Inst& inst, ScalarF32 lhs, ScalarF32 rhs) {
  246. Compare(ctx, inst, lhs, rhs, "SGT", "F", true);
  247. }
  248. void EmitFPOrdGreaterThan64(EmitContext& ctx, IR::Inst& inst, ScalarF64 lhs, ScalarF64 rhs) {
  249. Compare(ctx, inst, lhs, rhs, "SGT", "F64", true);
  250. }
  251. void EmitFPUnordGreaterThan16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register lhs,
  252. [[maybe_unused]] Register rhs) {
  253. throw NotImplementedException("GLASM instruction");
  254. }
  255. void EmitFPUnordGreaterThan32(EmitContext& ctx, IR::Inst& inst, ScalarF32 lhs, ScalarF32 rhs) {
  256. Compare(ctx, inst, lhs, rhs, "SGT", "F", false);
  257. }
  258. void EmitFPUnordGreaterThan64(EmitContext& ctx, IR::Inst& inst, ScalarF64 lhs, ScalarF64 rhs) {
  259. Compare(ctx, inst, lhs, rhs, "SGT", "F64", false);
  260. }
  261. void EmitFPOrdLessThanEqual16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register lhs,
  262. [[maybe_unused]] Register rhs) {
  263. throw NotImplementedException("GLASM instruction");
  264. }
  265. void EmitFPOrdLessThanEqual32(EmitContext& ctx, IR::Inst& inst, ScalarF32 lhs, ScalarF32 rhs) {
  266. Compare(ctx, inst, lhs, rhs, "SLE", "F", true);
  267. }
  268. void EmitFPOrdLessThanEqual64(EmitContext& ctx, IR::Inst& inst, ScalarF64 lhs, ScalarF64 rhs) {
  269. Compare(ctx, inst, lhs, rhs, "SLE", "F64", true);
  270. }
  271. void EmitFPUnordLessThanEqual16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register lhs,
  272. [[maybe_unused]] Register rhs) {
  273. throw NotImplementedException("GLASM instruction");
  274. }
  275. void EmitFPUnordLessThanEqual32(EmitContext& ctx, IR::Inst& inst, ScalarF32 lhs, ScalarF32 rhs) {
  276. Compare(ctx, inst, lhs, rhs, "SLE", "F", false);
  277. }
  278. void EmitFPUnordLessThanEqual64(EmitContext& ctx, IR::Inst& inst, ScalarF64 lhs, ScalarF64 rhs) {
  279. Compare(ctx, inst, lhs, rhs, "SLE", "F64", false);
  280. }
  281. void EmitFPOrdGreaterThanEqual16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register lhs,
  282. [[maybe_unused]] Register rhs) {
  283. throw NotImplementedException("GLASM instruction");
  284. }
  285. void EmitFPOrdGreaterThanEqual32(EmitContext& ctx, IR::Inst& inst, ScalarF32 lhs, ScalarF32 rhs) {
  286. Compare(ctx, inst, lhs, rhs, "SGE", "F", true);
  287. }
  288. void EmitFPOrdGreaterThanEqual64(EmitContext& ctx, IR::Inst& inst, ScalarF64 lhs, ScalarF64 rhs) {
  289. Compare(ctx, inst, lhs, rhs, "SGE", "F64", true);
  290. }
  291. void EmitFPUnordGreaterThanEqual16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register lhs,
  292. [[maybe_unused]] Register rhs) {
  293. throw NotImplementedException("GLASM instruction");
  294. }
  295. void EmitFPUnordGreaterThanEqual32(EmitContext& ctx, IR::Inst& inst, ScalarF32 lhs, ScalarF32 rhs) {
  296. Compare(ctx, inst, lhs, rhs, "SGE", "F", false);
  297. }
  298. void EmitFPUnordGreaterThanEqual64(EmitContext& ctx, IR::Inst& inst, ScalarF64 lhs, ScalarF64 rhs) {
  299. Compare(ctx, inst, lhs, rhs, "SGE", "F64", false);
  300. }
  301. void EmitFPIsNan16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) {
  302. throw NotImplementedException("GLASM instruction");
  303. }
  304. void EmitFPIsNan32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value) {
  305. Compare(ctx, inst, value, value, "SNE", "F", true, false);
  306. }
  307. void EmitFPIsNan64(EmitContext& ctx, IR::Inst& inst, ScalarF64 value) {
  308. Compare(ctx, inst, value, value, "SNE", "F64", true, false);
  309. }
  310. } // namespace Shader::Backend::GLASM