/src/test/assembly/asm/x86-modifiers.rs

https://gitlab.com/rust-lang/rust · Rust · 205 lines · 62 code · 31 blank · 112 comment · 1 complexity · 2e9f38e5fac65893d6400ec0dcdd6a21 MD5 · raw file

  1. // revisions: x86_64 i686
  2. // assembly-output: emit-asm
  3. // compile-flags: -O
  4. //[x86_64] compile-flags: --target x86_64-unknown-linux-gnu
  5. //[x86_64] needs-llvm-components: x86
  6. //[i686] compile-flags: --target i686-unknown-linux-gnu
  7. //[i686] needs-llvm-components: x86
  8. // compile-flags: -C llvm-args=--x86-asm-syntax=intel
  9. // compile-flags: -C target-feature=+avx512bw
  10. #![feature(no_core, lang_items, rustc_attrs)]
  11. #![crate_type = "rlib"]
  12. #![no_core]
  13. #![allow(asm_sub_register)]
  14. #[rustc_builtin_macro]
  15. macro_rules! asm {
  16. () => {};
  17. }
  18. #[rustc_builtin_macro]
  19. macro_rules! concat {
  20. () => {};
  21. }
  22. #[rustc_builtin_macro]
  23. macro_rules! stringify {
  24. () => {};
  25. }
  26. #[lang = "sized"]
  27. trait Sized {}
  28. #[lang = "copy"]
  29. trait Copy {}
  30. impl Copy for i32 {}
  31. macro_rules! check {
  32. ($func:ident $modifier:literal $reg:ident $mov:literal) => {
  33. // -O and extern "C" guarantee that the selected register is always ax/xmm0
  34. #[no_mangle]
  35. pub unsafe extern "C" fn $func() -> i32 {
  36. // Hack to avoid function merging
  37. extern "Rust" {
  38. fn dont_merge(s: &str);
  39. }
  40. dont_merge(stringify!($func));
  41. let y;
  42. asm!(concat!($mov, " {0:", $modifier, "}, {0:", $modifier, "}"), out($reg) y);
  43. y
  44. }
  45. };
  46. }
  47. // CHECK-LABEL: reg:
  48. // CHECK: #APP
  49. // x86_64: mov rax, rax
  50. // i686: mov eax, eax
  51. // CHECK: #NO_APP
  52. check!(reg "" reg "mov");
  53. // x86_64-LABEL: reg_l:
  54. // x86_64: #APP
  55. // x86_64: mov al, al
  56. // x86_64: #NO_APP
  57. #[cfg(x86_64)]
  58. check!(reg_l "l" reg "mov");
  59. // CHECK-LABEL: reg_x:
  60. // CHECK: #APP
  61. // CHECK: mov ax, ax
  62. // CHECK: #NO_APP
  63. check!(reg_x "x" reg "mov");
  64. // CHECK-LABEL: reg_e:
  65. // CHECK: #APP
  66. // CHECK: mov eax, eax
  67. // CHECK: #NO_APP
  68. check!(reg_e "e" reg "mov");
  69. // x86_64-LABEL: reg_r:
  70. // x86_64: #APP
  71. // x86_64: mov rax, rax
  72. // x86_64: #NO_APP
  73. #[cfg(x86_64)]
  74. check!(reg_r "r" reg "mov");
  75. // CHECK-LABEL: reg_abcd:
  76. // CHECK: #APP
  77. // x86_64: mov rax, rax
  78. // i686: mov eax, eax
  79. // CHECK: #NO_APP
  80. check!(reg_abcd "" reg_abcd "mov");
  81. // CHECK-LABEL: reg_abcd_l:
  82. // CHECK: #APP
  83. // CHECK: mov al, al
  84. // CHECK: #NO_APP
  85. check!(reg_abcd_l "l" reg_abcd "mov");
  86. // CHECK-LABEL: reg_abcd_h:
  87. // CHECK: #APP
  88. // CHECK: mov ah, ah
  89. // CHECK: #NO_APP
  90. check!(reg_abcd_h "h" reg_abcd "mov");
  91. // CHECK-LABEL: reg_abcd_x:
  92. // CHECK: #APP
  93. // CHECK: mov ax, ax
  94. // CHECK: #NO_APP
  95. check!(reg_abcd_x "x" reg_abcd "mov");
  96. // CHECK-LABEL: reg_abcd_e:
  97. // CHECK: #APP
  98. // CHECK: mov eax, eax
  99. // CHECK: #NO_APP
  100. check!(reg_abcd_e "e" reg_abcd "mov");
  101. // x86_64-LABEL: reg_abcd_r:
  102. // x86_64: #APP
  103. // x86_64: mov rax, rax
  104. // x86_64: #NO_APP
  105. #[cfg(x86_64)]
  106. check!(reg_abcd_r "r" reg_abcd "mov");
  107. // CHECK-LABEL: xmm_reg
  108. // CHECK: #APP
  109. // CHECK: movaps xmm0, xmm0
  110. // CHECK: #NO_APP
  111. check!(xmm_reg "" xmm_reg "movaps");
  112. // CHECK-LABEL: xmm_reg_x
  113. // CHECK: #APP
  114. // CHECK: movaps xmm0, xmm0
  115. // CHECK: #NO_APP
  116. check!(xmm_reg_x "x" xmm_reg "movaps");
  117. // CHECK-LABEL: xmm_reg_y
  118. // CHECK: #APP
  119. // CHECK: vmovaps ymm0, ymm0
  120. // CHECK: #NO_APP
  121. check!(xmm_reg_y "y" xmm_reg "vmovaps");
  122. // CHECK-LABEL: xmm_reg_z
  123. // CHECK: #APP
  124. // CHECK: vmovaps zmm0, zmm0
  125. // CHECK: #NO_APP
  126. check!(xmm_reg_z "z" xmm_reg "vmovaps");
  127. // CHECK-LABEL: ymm_reg
  128. // CHECK: #APP
  129. // CHECK: movaps ymm0, ymm0
  130. // CHECK: #NO_APP
  131. check!(ymm_reg "" ymm_reg "vmovaps");
  132. // CHECK-LABEL: ymm_reg_x
  133. // CHECK: #APP
  134. // CHECK: movaps xmm0, xmm0
  135. // CHECK: #NO_APP
  136. check!(ymm_reg_x "x" ymm_reg "movaps");
  137. // CHECK-LABEL: ymm_reg_y
  138. // CHECK: #APP
  139. // CHECK: vmovaps ymm0, ymm0
  140. // CHECK: #NO_APP
  141. check!(ymm_reg_y "y" ymm_reg "vmovaps");
  142. // CHECK-LABEL: ymm_reg_z
  143. // CHECK: #APP
  144. // CHECK: vmovaps zmm0, zmm0
  145. // CHECK: #NO_APP
  146. check!(ymm_reg_z "z" ymm_reg "vmovaps");
  147. // CHECK-LABEL: zmm_reg
  148. // CHECK: #APP
  149. // CHECK: movaps zmm0, zmm0
  150. // CHECK: #NO_APP
  151. check!(zmm_reg "" zmm_reg "vmovaps");
  152. // CHECK-LABEL: zmm_reg_x
  153. // CHECK: #APP
  154. // CHECK: movaps xmm0, xmm0
  155. // CHECK: #NO_APP
  156. check!(zmm_reg_x "x" zmm_reg "movaps");
  157. // CHECK-LABEL: zmm_reg_y
  158. // CHECK: #APP
  159. // CHECK: vmovaps ymm0, ymm0
  160. // CHECK: #NO_APP
  161. check!(zmm_reg_y "y" zmm_reg "vmovaps");
  162. // CHECK-LABEL: zmm_reg_z
  163. // CHECK: #APP
  164. // CHECK: vmovaps zmm0, zmm0
  165. // CHECK: #NO_APP
  166. check!(zmm_reg_z "z" zmm_reg "vmovaps");
  167. // Note: we don't have any way of ensuring that k1 is actually the register
  168. // chosen by the register allocator, so this check may fail if a different
  169. // register is chosen.
  170. // CHECK-LABEL: kreg:
  171. // CHECK: #APP
  172. // CHECK: kmovb k1, k1
  173. // CHECK: #NO_APP
  174. check!(kreg "" kreg "kmovb");