target-riscv.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. #include "lib.h"
  2. #include "symbol.h"
  3. #include "target.h"
  4. #include "machine.h"
  5. #include <string.h>
  6. #define RISCV_32BIT (1 << 0)
  7. #define RISCV_64BIT (1 << 1)
  8. #define RISCV_MUL (1 << 2)
  9. #define RISCV_DIV (1 << 3)
  10. #define RISCV_ATOMIC (1 << 4)
  11. #define RISCV_FLOAT (1 << 5)
  12. #define RISCV_DOUBLE (1 << 6)
  13. #define RISCV_FDIV (1 << 7)
  14. #define RISCV_COMP (1 << 8)
  15. #define RISCV_EMBD (1 << 9)
  16. #define RISCV_FPU (RISCV_FLOAT|RISCV_DOUBLE|RISCV_FDIV)
  17. #define RISCV_GENERIC (RISCV_MUL|RISCV_DIV|RISCV_ATOMIC|RISCV_FPU)
  18. static unsigned int riscv_flags;
  19. static void parse_march_riscv(const char *arg)
  20. {
  21. static struct {
  22. const char *pattern;
  23. unsigned int flags;
  24. } basic_sets[] = {
  25. { "rv32i", RISCV_32BIT },
  26. { "rv32e", RISCV_32BIT|RISCV_EMBD },
  27. { "rv32g", RISCV_32BIT|RISCV_GENERIC },
  28. { "rv64i", RISCV_64BIT },
  29. { "rv64g", RISCV_64BIT|RISCV_GENERIC },
  30. }, extensions[] = {
  31. { "m", RISCV_MUL|RISCV_DIV },
  32. { "a", RISCV_ATOMIC },
  33. { "f", RISCV_FLOAT|RISCV_FDIV },
  34. { "d", RISCV_DOUBLE|RISCV_FDIV },
  35. { "g", RISCV_GENERIC },
  36. { "q", 0 },
  37. { "l", 0 },
  38. { "c", RISCV_COMP },
  39. { "b", 0 },
  40. { "j", 0 },
  41. { "t", 0 },
  42. { "p", 0 },
  43. { "v", 0 },
  44. { "n", 0 },
  45. { "h", 0 },
  46. { "s", 0 },
  47. };
  48. int i;
  49. for (i = 0; i < ARRAY_SIZE(basic_sets); i++) {
  50. const char *pat = basic_sets[i].pattern;
  51. size_t len = strlen(pat);
  52. if (!strncmp(arg, pat, len)) {
  53. riscv_flags |= basic_sets[i].flags;
  54. arg += len;
  55. goto ext;
  56. }
  57. }
  58. die("invalid argument to '-march': '%s'\n", arg);
  59. ext:
  60. for (i = 0; i < ARRAY_SIZE(extensions); i++) {
  61. const char *pat = extensions[i].pattern;
  62. size_t len = strlen(pat);
  63. if (!strncmp(arg, pat, len)) {
  64. riscv_flags |= extensions[i].flags;
  65. arg += len;
  66. }
  67. }
  68. if (arg[0])
  69. die("invalid argument to '-march': '%s'\n", arg);
  70. }
  71. static void init_riscv(const struct target *self)
  72. {
  73. if (arch_cmodel == CMODEL_UNKNOWN)
  74. arch_cmodel = CMODEL_MEDLOW;
  75. if (fpic)
  76. arch_cmodel = CMODEL_PIC;
  77. if (riscv_flags == 0)
  78. riscv_flags = self->flags;
  79. }
  80. static void init_riscv32(const struct target *self)
  81. {
  82. fast16_ctype = &int_ctype;
  83. ufast16_ctype = &uint_ctype;
  84. fast32_ctype = &int_ctype;
  85. ufast32_ctype = &uint_ctype;
  86. init_riscv(self);
  87. }
  88. static void predefine_riscv(const struct target *self)
  89. {
  90. static const char *cmodels[CMODEL_LAST] = {
  91. [CMODEL_MEDANY] = "medany",
  92. [CMODEL_MEDLOW] = "medlow",
  93. [CMODEL_PIC] = "pic",
  94. };
  95. const char *cmodel = cmodels[arch_cmodel];
  96. predefine("__riscv", 1, "1");
  97. predefine("__riscv_xlen", 1, "%d", ptr_ctype.bit_size);
  98. if (riscv_flags & RISCV_ATOMIC)
  99. predefine("__riscv_atomic", 1, "1");
  100. if (riscv_flags & RISCV_COMP)
  101. predefine("__riscv_compressed", 1, "1");
  102. if (riscv_flags & RISCV_DIV)
  103. predefine("__riscv_div", 1, "1");
  104. if (riscv_flags & RISCV_EMBD)
  105. predefine("__riscv_32e", 1, "1");
  106. if (riscv_flags & RISCV_FPU)
  107. predefine("__riscv_flen", 1, "%d", (riscv_flags & RISCV_DOUBLE) ? 64 : 32);
  108. if (riscv_flags & RISCV_FDIV)
  109. predefine("__riscv_fdiv", 1, "1");
  110. if (riscv_flags & RISCV_FDIV)
  111. predefine("__riscv_fsqrt", 1, "1");
  112. if (riscv_flags & RISCV_MUL)
  113. predefine("__riscv_mul", 1, "1");
  114. if ((riscv_flags & RISCV_MUL) && (riscv_flags & RISCV_DIV))
  115. predefine("__riscv_muldiv", 1, "1");
  116. if (cmodel)
  117. predefine_strong("__riscv_cmodel_%s", cmodel);
  118. }
  119. const struct target target_riscv32 = {
  120. .mach = MACH_RISCV32,
  121. .bitness = ARCH_LP32,
  122. .big_endian = 0,
  123. .unsigned_char = 1,
  124. .flags = RISCV_32BIT|RISCV_GENERIC|RISCV_COMP,
  125. .target_64bit = &target_riscv64,
  126. .init = init_riscv32,
  127. .predefine = predefine_riscv,
  128. .parse_march = parse_march_riscv,
  129. };
  130. const struct target target_riscv64 = {
  131. .mach = MACH_RISCV64,
  132. .bitness = ARCH_LP64,
  133. .big_endian = 0,
  134. .unsigned_char = 1,
  135. .has_int128 = 1,
  136. .flags = RISCV_64BIT|RISCV_GENERIC|RISCV_COMP,
  137. .target_32bit = &target_riscv32,
  138. .init = init_riscv,
  139. .predefine = predefine_riscv,
  140. .parse_march = parse_march_riscv,
  141. };