instructions.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. // SPDX-License-Identifier: GPL-2.0
  2. static int is_branch_cond(const char *cond)
  3. {
  4. if (cond[0] == '\0')
  5. return 1;
  6. if (cond[0] == 'a' && cond[1] == '\0')
  7. return 1;
  8. if (cond[0] == 'c' &&
  9. (cond[1] == 'c' || cond[1] == 's') &&
  10. cond[2] == '\0')
  11. return 1;
  12. if (cond[0] == 'e' &&
  13. (cond[1] == '\0' ||
  14. (cond[1] == 'q' && cond[2] == '\0')))
  15. return 1;
  16. if (cond[0] == 'g' &&
  17. (cond[1] == '\0' ||
  18. (cond[1] == 't' && cond[2] == '\0') ||
  19. (cond[1] == 'e' && cond[2] == '\0') ||
  20. (cond[1] == 'e' && cond[2] == 'u' && cond[3] == '\0')))
  21. return 1;
  22. if (cond[0] == 'l' &&
  23. (cond[1] == '\0' ||
  24. (cond[1] == 't' && cond[2] == '\0') ||
  25. (cond[1] == 'u' && cond[2] == '\0') ||
  26. (cond[1] == 'e' && cond[2] == '\0') ||
  27. (cond[1] == 'e' && cond[2] == 'u' && cond[3] == '\0')))
  28. return 1;
  29. if (cond[0] == 'n' &&
  30. (cond[1] == '\0' ||
  31. (cond[1] == 'e' && cond[2] == '\0') ||
  32. (cond[1] == 'z' && cond[2] == '\0') ||
  33. (cond[1] == 'e' && cond[2] == 'g' && cond[3] == '\0')))
  34. return 1;
  35. if (cond[0] == 'b' &&
  36. cond[1] == 'p' &&
  37. cond[2] == 'o' &&
  38. cond[3] == 's' &&
  39. cond[4] == '\0')
  40. return 1;
  41. if (cond[0] == 'v' &&
  42. (cond[1] == 'c' || cond[1] == 's') &&
  43. cond[2] == '\0')
  44. return 1;
  45. if (cond[0] == 'b' &&
  46. cond[1] == 'z' &&
  47. cond[2] == '\0')
  48. return 1;
  49. return 0;
  50. }
  51. static int is_branch_reg_cond(const char *cond)
  52. {
  53. if ((cond[0] == 'n' || cond[0] == 'l') &&
  54. cond[1] == 'z' &&
  55. cond[2] == '\0')
  56. return 1;
  57. if (cond[0] == 'z' &&
  58. cond[1] == '\0')
  59. return 1;
  60. if ((cond[0] == 'g' || cond[0] == 'l') &&
  61. cond[1] == 'e' &&
  62. cond[2] == 'z' &&
  63. cond[3] == '\0')
  64. return 1;
  65. if (cond[0] == 'g' &&
  66. cond[1] == 'z' &&
  67. cond[2] == '\0')
  68. return 1;
  69. return 0;
  70. }
  71. static int is_branch_float_cond(const char *cond)
  72. {
  73. if (cond[0] == '\0')
  74. return 1;
  75. if ((cond[0] == 'a' || cond[0] == 'e' ||
  76. cond[0] == 'z' || cond[0] == 'g' ||
  77. cond[0] == 'l' || cond[0] == 'n' ||
  78. cond[0] == 'o' || cond[0] == 'u') &&
  79. cond[1] == '\0')
  80. return 1;
  81. if (((cond[0] == 'g' && cond[1] == 'e') ||
  82. (cond[0] == 'l' && (cond[1] == 'e' ||
  83. cond[1] == 'g')) ||
  84. (cond[0] == 'n' && (cond[1] == 'e' ||
  85. cond[1] == 'z')) ||
  86. (cond[0] == 'u' && (cond[1] == 'e' ||
  87. cond[1] == 'g' ||
  88. cond[1] == 'l'))) &&
  89. cond[2] == '\0')
  90. return 1;
  91. if (cond[0] == 'u' &&
  92. (cond[1] == 'g' || cond[1] == 'l') &&
  93. cond[2] == 'e' &&
  94. cond[3] == '\0')
  95. return 1;
  96. return 0;
  97. }
  98. static struct ins_ops *sparc__associate_instruction_ops(struct arch *arch, const char *name)
  99. {
  100. struct ins_ops *ops = NULL;
  101. if (!strcmp(name, "call") ||
  102. !strcmp(name, "jmp") ||
  103. !strcmp(name, "jmpl")) {
  104. ops = &call_ops;
  105. } else if (!strcmp(name, "ret") ||
  106. !strcmp(name, "retl") ||
  107. !strcmp(name, "return")) {
  108. ops = &ret_ops;
  109. } else if (!strcmp(name, "mov")) {
  110. ops = &mov_ops;
  111. } else {
  112. if (name[0] == 'c' &&
  113. (name[1] == 'w' || name[1] == 'x'))
  114. name += 2;
  115. if (name[0] == 'b') {
  116. const char *cond = name + 1;
  117. if (cond[0] == 'r') {
  118. if (is_branch_reg_cond(cond + 1))
  119. ops = &jump_ops;
  120. } else if (is_branch_cond(cond)) {
  121. ops = &jump_ops;
  122. }
  123. } else if (name[0] == 'f' && name[1] == 'b') {
  124. if (is_branch_float_cond(name + 2))
  125. ops = &jump_ops;
  126. }
  127. }
  128. if (ops)
  129. arch__associate_ins_ops(arch, name, ops);
  130. return ops;
  131. }
  132. static int sparc__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
  133. {
  134. if (!arch->initialized) {
  135. arch->initialized = true;
  136. arch->associate_instruction_ops = sparc__associate_instruction_ops;
  137. arch->objdump.comment_char = '#';
  138. }
  139. return 0;
  140. }