pswt.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. #include "gc.h"
  2. int
  3. swcmp(void *a1, void *a2)
  4. {
  5. C1 *p1, *p2;
  6. p1 = (C1*)a1;
  7. p2 = (C1*)a2;
  8. if(p1->val < p2->val)
  9. return -1;
  10. return p1->val > p2->val;
  11. }
  12. void
  13. doswit(Node *n)
  14. {
  15. Case *c;
  16. C1 *q, *iq, *iqh, *iql;
  17. long def, nc, i, j, isv, nh;
  18. Prog *hsb;
  19. Node *vr[2];
  20. int dup;
  21. def = 0;
  22. nc = 0;
  23. isv = 0;
  24. for(c = cases; c->link != C; c = c->link) {
  25. if(c->def) {
  26. if(def)
  27. diag(n, "more than one default in switch");
  28. def = c->label;
  29. continue;
  30. }
  31. isv |= c->isv;
  32. nc++;
  33. }
  34. if(typev[n->type->etype])
  35. isv = 1;
  36. else if(isv){
  37. warn(n, "32-bit switch expression with 64-bit case constant");
  38. isv = 0;
  39. }
  40. iq = alloc(nc*sizeof(C1));
  41. q = iq;
  42. for(c = cases; c->link != C; c = c->link) {
  43. if(c->def)
  44. continue;
  45. if(c->isv && !isv)
  46. continue; /* can never match */
  47. q->label = c->label;
  48. if(isv)
  49. q->val = c->val;
  50. else
  51. q->val = (long)c->val; /* cast ensures correct value for 32-bit switch on 64-bit architecture */
  52. q++;
  53. }
  54. qsort(iq, nc, sizeof(C1), swcmp);
  55. if(debug['K'])
  56. for(i=0; i<nc; i++)
  57. print("case %2ld: = %.8llux\n", i, (vlong)iq[i].val);
  58. dup = 0;
  59. for(i=0; i<nc-1; i++)
  60. if(iq[i].val == iq[i+1].val) {
  61. diag(n, "duplicate cases in switch %lld", (vlong)iq[i].val);
  62. dup = 1;
  63. }
  64. if(dup)
  65. return;
  66. if(def == 0) {
  67. def = breakpc;
  68. nbreak++;
  69. }
  70. if(!isv || ewidth[TIND] > ewidth[TLONG] || n->op == OREGISTER) {
  71. swit1(iq, nc, def, n);
  72. return;
  73. }
  74. /*
  75. * 64-bit case on 32-bit machine:
  76. * switch on high-order words, and
  77. * in each of those, switch on low-order words
  78. */
  79. if(n->op != OREGPAIR)
  80. fatal(n, "internal: expected register pair");
  81. if(thechar == '8'){ /* TO DO: need an enquiry function */
  82. vr[0] = n->left; /* low */
  83. vr[1] = n->right; /* high */
  84. }else{
  85. vr[0] = n->right;
  86. vr[1] = n->left;
  87. }
  88. vr[0]->type = types[TLONG];
  89. vr[1]->type = types[TLONG];
  90. gbranch(OGOTO);
  91. hsb = p;
  92. iqh = alloc(nc*sizeof(C1));
  93. iql = alloc(nc*sizeof(C1));
  94. nh = 0;
  95. for(i=0; i<nc;){
  96. iqh[nh].val = iq[i].val >> 32;
  97. q = iql;
  98. /* iq is sorted, so equal top halves are adjacent */
  99. for(j = i; j < nc; j++){
  100. if((iq[j].val>>32) != iqh[nh].val)
  101. break;
  102. q->val = (long)iq[j].val;
  103. q->label = iq[j].label;
  104. q++;
  105. }
  106. qsort(iql, q-iql, sizeof(C1), swcmp);
  107. iqh[nh].label = pc;
  108. nh++;
  109. swit1(iql, q-iql, def, vr[0]);
  110. i = j;
  111. }
  112. patch(hsb, pc);
  113. swit1(iqh, nh, def, vr[1]);
  114. }
  115. void
  116. casf(void)
  117. {
  118. Case *c;
  119. c = alloc(sizeof(*c));
  120. c->link = cases;
  121. cases = c;
  122. }
  123. long
  124. outlstring(TRune *s, long n)
  125. {
  126. char buf[sizeof(TRune)];
  127. uint c;
  128. int i;
  129. long r;
  130. if(suppress)
  131. return nstring;
  132. while(nstring & (sizeof(TRune)-1))
  133. outstring("", 1);
  134. r = nstring;
  135. while(n > 0) {
  136. c = *s++;
  137. if(align(0, types[TCHAR], Aarg1)) {
  138. for(i = 0; i < sizeof(TRune); i++)
  139. buf[i] = c>>(8*(sizeof(TRune) - i - 1));
  140. } else {
  141. for(i = 0; i < sizeof(TRune); i++)
  142. buf[i] = c>>(8*i);
  143. }
  144. outstring(buf, sizeof(TRune));
  145. n -= sizeof(TRune);
  146. }
  147. return r;
  148. }
  149. void
  150. nullwarn(Node *l, Node *r)
  151. {
  152. warn(Z, "result of operation not used");
  153. if(l != Z)
  154. cgen(l, Z);
  155. if(r != Z)
  156. cgen(r, Z);
  157. }
  158. void
  159. ieeedtod(Ieee *ieee, double native)
  160. {
  161. double fr, ho, f;
  162. int exp;
  163. if(native < 0) {
  164. ieeedtod(ieee, -native);
  165. ieee->h |= 0x80000000L;
  166. return;
  167. }
  168. if(native == 0) {
  169. ieee->l = 0;
  170. ieee->h = 0;
  171. return;
  172. }
  173. fr = frexp(native, &exp);
  174. f = 2097152L; /* shouldnt use fp constants here */
  175. fr = modf(fr*f, &ho);
  176. ieee->h = ho;
  177. ieee->h &= 0xfffffL;
  178. ieee->h |= (exp+1022L) << 20;
  179. f = 65536L;
  180. fr = modf(fr*f, &ho);
  181. ieee->l = ho;
  182. ieee->l <<= 16;
  183. ieee->l |= (long)(fr*f);
  184. }