/gcc-reload-optional.patch

# · Patch · 679 lines · 674 code · 5 blank · 0 comment · 0 complexity · 2fd7fcf83975a0fa80a87413e46a66ab MD5 · raw file

  1. 2001-11-12 Jakub Jelinek <jakub@redhat.com>
  2. * reload.c (find_reloads): Emit USE resp. CLOBBER insns if not
  3. pushing any reloads if needed.
  4. * gcc.dg/20011024-1.c: New test.
  5. --- gcc/reload.c.jj Wed Oct 24 21:25:01 2001
  6. +++ gcc/reload.c Mon Nov 12 12:43:52 2001
  7. @@ -3621,53 +3621,144 @@ find_reloads (insn, replace, ind_levels,
  8. /* Now record reloads for all the operands that need them. */
  9. for (i = 0; i < noperands; i++)
  10. - if (! goal_alternative_win[i])
  11. - {
  12. - /* Operands that match previous ones have already been handled. */
  13. - if (goal_alternative_matches[i] >= 0)
  14. - ;
  15. - /* Handle an operand with a nonoffsettable address
  16. - appearing where an offsettable address will do
  17. - by reloading the address into a base register.
  18. -
  19. - ??? We can also do this when the operand is a register and
  20. - reg_equiv_mem is not offsettable, but this is a bit tricky,
  21. - so we don't bother with it. It may not be worth doing. */
  22. - else if (goal_alternative_matched[i] == -1
  23. - && goal_alternative_offmemok[i]
  24. - && GET_CODE (recog_data.operand[i]) == MEM)
  25. - {
  26. - operand_reloadnum[i]
  27. - = push_reload (XEXP (recog_data.operand[i], 0), NULL_RTX,
  28. - &XEXP (recog_data.operand[i], 0), NULL_PTR,
  29. - BASE_REG_CLASS,
  30. - GET_MODE (XEXP (recog_data.operand[i], 0)),
  31. - VOIDmode, 0, 0, i, RELOAD_FOR_INPUT);
  32. - rld[operand_reloadnum[i]].inc
  33. - = GET_MODE_SIZE (GET_MODE (recog_data.operand[i]));
  34. -
  35. - /* If this operand is an output, we will have made any
  36. - reloads for its address as RELOAD_FOR_OUTPUT_ADDRESS, but
  37. - now we are treating part of the operand as an input, so
  38. - we must change these to RELOAD_FOR_INPUT_ADDRESS. */
  39. -
  40. - if (modified[i] == RELOAD_WRITE)
  41. - {
  42. - for (j = 0; j < n_reloads; j++)
  43. - {
  44. - if (rld[j].opnum == i)
  45. - {
  46. - if (rld[j].when_needed == RELOAD_FOR_OUTPUT_ADDRESS)
  47. - rld[j].when_needed = RELOAD_FOR_INPUT_ADDRESS;
  48. - else if (rld[j].when_needed
  49. - == RELOAD_FOR_OUTADDR_ADDRESS)
  50. - rld[j].when_needed = RELOAD_FOR_INPADDR_ADDRESS;
  51. - }
  52. - }
  53. - }
  54. - }
  55. - else if (goal_alternative_matched[i] == -1)
  56. - {
  57. + {
  58. + if (! goal_alternative_win[i])
  59. + {
  60. + /* Operands that match previous ones have already been handled. */
  61. + if (goal_alternative_matches[i] >= 0)
  62. + ;
  63. + /* Handle an operand with a nonoffsettable address
  64. + appearing where an offsettable address will do
  65. + by reloading the address into a base register.
  66. +
  67. + ??? We can also do this when the operand is a register and
  68. + reg_equiv_mem is not offsettable, but this is a bit tricky,
  69. + so we don't bother with it. It may not be worth doing. */
  70. + else if (goal_alternative_matched[i] == -1
  71. + && goal_alternative_offmemok[i]
  72. + && GET_CODE (recog_data.operand[i]) == MEM)
  73. + {
  74. + operand_reloadnum[i]
  75. + = push_reload (XEXP (recog_data.operand[i], 0), NULL_RTX,
  76. + &XEXP (recog_data.operand[i], 0), NULL_PTR,
  77. + BASE_REG_CLASS,
  78. + GET_MODE (XEXP (recog_data.operand[i], 0)),
  79. + VOIDmode, 0, 0, i, RELOAD_FOR_INPUT);
  80. + rld[operand_reloadnum[i]].inc
  81. + = GET_MODE_SIZE (GET_MODE (recog_data.operand[i]));
  82. +
  83. + /* If this operand is an output, we will have made any
  84. + reloads for its address as RELOAD_FOR_OUTPUT_ADDRESS, but
  85. + now we are treating part of the operand as an input, so
  86. + we must change these to RELOAD_FOR_INPUT_ADDRESS. */
  87. +
  88. + if (modified[i] == RELOAD_WRITE)
  89. + {
  90. + for (j = 0; j < n_reloads; j++)
  91. + {
  92. + if (rld[j].opnum == i)
  93. + {
  94. + if (rld[j].when_needed == RELOAD_FOR_OUTPUT_ADDRESS)
  95. + rld[j].when_needed = RELOAD_FOR_INPUT_ADDRESS;
  96. + else if (rld[j].when_needed
  97. + == RELOAD_FOR_OUTADDR_ADDRESS)
  98. + rld[j].when_needed = RELOAD_FOR_INPADDR_ADDRESS;
  99. + }
  100. + }
  101. + }
  102. + }
  103. + else if (goal_alternative_matched[i] == -1)
  104. + {
  105. + operand_reloadnum[i]
  106. + = push_reload ((modified[i] != RELOAD_WRITE
  107. + ? recog_data.operand[i] : 0),
  108. + (modified[i] != RELOAD_READ
  109. + ? recog_data.operand[i] : 0),
  110. + (modified[i] != RELOAD_WRITE
  111. + ? recog_data.operand_loc[i] : 0),
  112. + (modified[i] != RELOAD_READ
  113. + ? recog_data.operand_loc[i] : 0),
  114. + (enum reg_class) goal_alternative[i],
  115. + (modified[i] == RELOAD_WRITE
  116. + ? VOIDmode : operand_mode[i]),
  117. + (modified[i] == RELOAD_READ
  118. + ? VOIDmode : operand_mode[i]),
  119. + (insn_code_number < 0 ? 0
  120. + : insn_data[insn_code_number].operand[i].strict_low),
  121. + 0, i, operand_type[i]);
  122. + }
  123. + /* In a matching pair of operands, one must be input only
  124. + and the other must be output only.
  125. + Pass the input operand as IN and the other as OUT. */
  126. + else if (modified[i] == RELOAD_READ
  127. + && modified[goal_alternative_matched[i]] == RELOAD_WRITE)
  128. + {
  129. + operand_reloadnum[i]
  130. + = push_reload (recog_data.operand[i],
  131. + recog_data.operand[goal_alternative_matched[i]],
  132. + recog_data.operand_loc[i],
  133. + recog_data.operand_loc[goal_alternative_matched[i]],
  134. + (enum reg_class) goal_alternative[i],
  135. + operand_mode[i],
  136. + operand_mode[goal_alternative_matched[i]],
  137. + 0, 0, i, RELOAD_OTHER);
  138. + operand_reloadnum[goal_alternative_matched[i]] = output_reloadnum;
  139. + }
  140. + else if (modified[i] == RELOAD_WRITE
  141. + && modified[goal_alternative_matched[i]] == RELOAD_READ)
  142. + {
  143. + operand_reloadnum[goal_alternative_matched[i]]
  144. + = push_reload (recog_data.operand[goal_alternative_matched[i]],
  145. + recog_data.operand[i],
  146. + recog_data.operand_loc[goal_alternative_matched[i]],
  147. + recog_data.operand_loc[i],
  148. + (enum reg_class) goal_alternative[i],
  149. + operand_mode[goal_alternative_matched[i]],
  150. + operand_mode[i],
  151. + 0, 0, i, RELOAD_OTHER);
  152. + operand_reloadnum[i] = output_reloadnum;
  153. + }
  154. + else if (insn_code_number >= 0)
  155. + abort ();
  156. + else
  157. + {
  158. + error_for_asm (insn, "inconsistent operand constraints in an `asm'");
  159. + /* Avoid further trouble with this insn. */
  160. + PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx);
  161. + n_reloads = 0;
  162. + return 0;
  163. + }
  164. + }
  165. + else if (goal_alternative_matched[i] < 0
  166. + && goal_alternative_matches[i] < 0
  167. + && optimize)
  168. + {
  169. + /* For each non-matching operand that's a MEM or a pseudo-register
  170. + that didn't get a hard register, make an optional reload.
  171. + This may get done even if the insn needs no reloads otherwise. */
  172. +
  173. + rtx operand = recog_data.operand[i];
  174. +
  175. + while (GET_CODE (operand) == SUBREG)
  176. + operand = SUBREG_REG (operand);
  177. + if ((GET_CODE (operand) == MEM
  178. + || (GET_CODE (operand) == REG
  179. + && REGNO (operand) >= FIRST_PSEUDO_REGISTER))
  180. + /* If this is only for an output, the optional reload would not
  181. + actually cause us to use a register now, just note that
  182. + something is stored here. */
  183. + && ((enum reg_class) goal_alternative[i] != NO_REGS
  184. + || modified[i] == RELOAD_WRITE)
  185. + && ! no_input_reloads
  186. + /* An optional output reload might allow to delete INSN later.
  187. + We mustn't make in-out reloads on insns that are not permitted
  188. + output reloads.
  189. + If this is an asm, we can't delete it; we must not even call
  190. + push_reload for an optional output reload in this case,
  191. + because we can't be sure that the constraint allows a register,
  192. + and push_reload verifies the constraints for asms. */
  193. + && (modified[i] == RELOAD_READ
  194. + || (! no_output_reloads && ! this_insn_is_asm)))
  195. operand_reloadnum[i]
  196. = push_reload ((modified[i] != RELOAD_WRITE
  197. ? recog_data.operand[i] : 0),
  198. @@ -3684,150 +3775,69 @@ find_reloads (insn, replace, ind_levels,
  199. ? VOIDmode : operand_mode[i]),
  200. (insn_code_number < 0 ? 0
  201. : insn_data[insn_code_number].operand[i].strict_low),
  202. - 0, i, operand_type[i]);
  203. - }
  204. - /* In a matching pair of operands, one must be input only
  205. - and the other must be output only.
  206. - Pass the input operand as IN and the other as OUT. */
  207. - else if (modified[i] == RELOAD_READ
  208. - && modified[goal_alternative_matched[i]] == RELOAD_WRITE)
  209. - {
  210. - operand_reloadnum[i]
  211. - = push_reload (recog_data.operand[i],
  212. - recog_data.operand[goal_alternative_matched[i]],
  213. - recog_data.operand_loc[i],
  214. - recog_data.operand_loc[goal_alternative_matched[i]],
  215. - (enum reg_class) goal_alternative[i],
  216. - operand_mode[i],
  217. - operand_mode[goal_alternative_matched[i]],
  218. - 0, 0, i, RELOAD_OTHER);
  219. - operand_reloadnum[goal_alternative_matched[i]] = output_reloadnum;
  220. - }
  221. - else if (modified[i] == RELOAD_WRITE
  222. - && modified[goal_alternative_matched[i]] == RELOAD_READ)
  223. - {
  224. - operand_reloadnum[goal_alternative_matched[i]]
  225. - = push_reload (recog_data.operand[goal_alternative_matched[i]],
  226. + 1, i, operand_type[i]);
  227. + }
  228. + else if (goal_alternative_matches[i] >= 0
  229. + && goal_alternative_win[goal_alternative_matches[i]]
  230. + && modified[i] == RELOAD_READ
  231. + && modified[goal_alternative_matches[i]] == RELOAD_WRITE
  232. + && ! no_input_reloads && ! no_output_reloads
  233. + && optimize)
  234. + {
  235. + /* Similarly, make an optional reload for a pair of matching
  236. + objects that are in MEM or a pseudo that didn't get a hard reg. */
  237. +
  238. + rtx operand = recog_data.operand[i];
  239. +
  240. + while (GET_CODE (operand) == SUBREG)
  241. + operand = SUBREG_REG (operand);
  242. + if ((GET_CODE (operand) == MEM
  243. + || (GET_CODE (operand) == REG
  244. + && REGNO (operand) >= FIRST_PSEUDO_REGISTER))
  245. + && ((enum reg_class) goal_alternative[goal_alternative_matches[i]]
  246. + != NO_REGS))
  247. + operand_reloadnum[i] = operand_reloadnum[goal_alternative_matches[i]]
  248. + = push_reload (recog_data.operand[goal_alternative_matches[i]],
  249. recog_data.operand[i],
  250. - recog_data.operand_loc[goal_alternative_matched[i]],
  251. + recog_data.operand_loc[goal_alternative_matches[i]],
  252. recog_data.operand_loc[i],
  253. - (enum reg_class) goal_alternative[i],
  254. - operand_mode[goal_alternative_matched[i]],
  255. + (enum reg_class) goal_alternative[goal_alternative_matches[i]],
  256. + operand_mode[goal_alternative_matches[i]],
  257. operand_mode[i],
  258. - 0, 0, i, RELOAD_OTHER);
  259. - operand_reloadnum[i] = output_reloadnum;
  260. - }
  261. - else if (insn_code_number >= 0)
  262. - abort ();
  263. - else
  264. - {
  265. - error_for_asm (insn, "inconsistent operand constraints in an `asm'");
  266. - /* Avoid further trouble with this insn. */
  267. - PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx);
  268. - n_reloads = 0;
  269. - return 0;
  270. - }
  271. - }
  272. - else if (goal_alternative_matched[i] < 0
  273. - && goal_alternative_matches[i] < 0
  274. - && optimize)
  275. - {
  276. - /* For each non-matching operand that's a MEM or a pseudo-register
  277. - that didn't get a hard register, make an optional reload.
  278. - This may get done even if the insn needs no reloads otherwise. */
  279. -
  280. - rtx operand = recog_data.operand[i];
  281. -
  282. - while (GET_CODE (operand) == SUBREG)
  283. - operand = SUBREG_REG (operand);
  284. - if ((GET_CODE (operand) == MEM
  285. - || (GET_CODE (operand) == REG
  286. - && REGNO (operand) >= FIRST_PSEUDO_REGISTER))
  287. - /* If this is only for an output, the optional reload would not
  288. - actually cause us to use a register now, just note that
  289. - something is stored here. */
  290. - && ((enum reg_class) goal_alternative[i] != NO_REGS
  291. - || modified[i] == RELOAD_WRITE)
  292. - && ! no_input_reloads
  293. - /* An optional output reload might allow to delete INSN later.
  294. - We mustn't make in-out reloads on insns that are not permitted
  295. - output reloads.
  296. - If this is an asm, we can't delete it; we must not even call
  297. - push_reload for an optional output reload in this case,
  298. - because we can't be sure that the constraint allows a register,
  299. - and push_reload verifies the constraints for asms. */
  300. - && (modified[i] == RELOAD_READ
  301. - || (! no_output_reloads && ! this_insn_is_asm)))
  302. - operand_reloadnum[i]
  303. - = push_reload ((modified[i] != RELOAD_WRITE
  304. - ? recog_data.operand[i] : 0),
  305. - (modified[i] != RELOAD_READ
  306. - ? recog_data.operand[i] : 0),
  307. - (modified[i] != RELOAD_WRITE
  308. - ? recog_data.operand_loc[i] : 0),
  309. - (modified[i] != RELOAD_READ
  310. - ? recog_data.operand_loc[i] : 0),
  311. - (enum reg_class) goal_alternative[i],
  312. - (modified[i] == RELOAD_WRITE
  313. - ? VOIDmode : operand_mode[i]),
  314. - (modified[i] == RELOAD_READ
  315. - ? VOIDmode : operand_mode[i]),
  316. - (insn_code_number < 0 ? 0
  317. - : insn_data[insn_code_number].operand[i].strict_low),
  318. - 1, i, operand_type[i]);
  319. - /* If a memory reference remains (either as a MEM or a pseudo that
  320. - did not get a hard register), yet we can't make an optional
  321. - reload, check if this is actually a pseudo register reference;
  322. - we then need to emit a USE and/or a CLOBBER so that reload
  323. - inheritance will do the right thing. */
  324. - else if (replace
  325. - && (GET_CODE (operand) == MEM
  326. - || (GET_CODE (operand) == REG
  327. - && REGNO (operand) >= FIRST_PSEUDO_REGISTER
  328. - && reg_renumber [REGNO (operand)] < 0)))
  329. - {
  330. - operand = *recog_data.operand_loc[i];
  331. -
  332. - while (GET_CODE (operand) == SUBREG)
  333. - operand = SUBREG_REG (operand);
  334. - if (GET_CODE (operand) == REG)
  335. - {
  336. - if (modified[i] != RELOAD_WRITE)
  337. - emit_insn_before (gen_rtx_USE (VOIDmode, operand), insn);
  338. - if (modified[i] != RELOAD_READ)
  339. - emit_insn_after (gen_rtx_CLOBBER (VOIDmode, operand), insn);
  340. - }
  341. - }
  342. - }
  343. - else if (goal_alternative_matches[i] >= 0
  344. - && goal_alternative_win[goal_alternative_matches[i]]
  345. - && modified[i] == RELOAD_READ
  346. - && modified[goal_alternative_matches[i]] == RELOAD_WRITE
  347. - && ! no_input_reloads && ! no_output_reloads
  348. - && optimize)
  349. - {
  350. - /* Similarly, make an optional reload for a pair of matching
  351. - objects that are in MEM or a pseudo that didn't get a hard reg. */
  352. -
  353. - rtx operand = recog_data.operand[i];
  354. -
  355. - while (GET_CODE (operand) == SUBREG)
  356. - operand = SUBREG_REG (operand);
  357. - if ((GET_CODE (operand) == MEM
  358. - || (GET_CODE (operand) == REG
  359. - && REGNO (operand) >= FIRST_PSEUDO_REGISTER))
  360. - && ((enum reg_class) goal_alternative[goal_alternative_matches[i]]
  361. - != NO_REGS))
  362. - operand_reloadnum[i] = operand_reloadnum[goal_alternative_matches[i]]
  363. - = push_reload (recog_data.operand[goal_alternative_matches[i]],
  364. - recog_data.operand[i],
  365. - recog_data.operand_loc[goal_alternative_matches[i]],
  366. - recog_data.operand_loc[i],
  367. - (enum reg_class) goal_alternative[goal_alternative_matches[i]],
  368. - operand_mode[goal_alternative_matches[i]],
  369. - operand_mode[i],
  370. - 0, 1, goal_alternative_matches[i], RELOAD_OTHER);
  371. - }
  372. + 0, 1, goal_alternative_matches[i], RELOAD_OTHER);
  373. + }
  374. +
  375. + /* If a memory reference remains (either as a MEM or a pseudo that
  376. + did not get a hard register), yet we can't make an optional
  377. + reload, check if this is actually a pseudo register reference;
  378. + we then need to emit a USE and/or a CLOBBER so that reload
  379. + inheritance will do the right thing. */
  380. + if (operand_reloadnum[i] == -1 && replace)
  381. + {
  382. + rtx operand = recog_data.operand[i];
  383. +
  384. + while (GET_CODE (operand) == SUBREG)
  385. + operand = SUBREG_REG (operand);
  386. +
  387. + if (GET_CODE (operand) == MEM
  388. + || (GET_CODE (operand) == REG
  389. + && REGNO (operand) >= FIRST_PSEUDO_REGISTER
  390. + && reg_renumber [REGNO (operand)] < 0))
  391. + {
  392. + operand = *recog_data.operand_loc[i];
  393. +
  394. + while (GET_CODE (operand) == SUBREG)
  395. + operand = SUBREG_REG (operand);
  396. + if (GET_CODE (operand) == REG)
  397. + {
  398. + if (modified[i] != RELOAD_WRITE)
  399. + emit_insn_before (gen_rtx_USE (VOIDmode, operand), insn);
  400. + if (modified[i] != RELOAD_READ)
  401. + emit_insn_after (gen_rtx_CLOBBER (VOIDmode, operand), insn);
  402. + }
  403. + }
  404. + }
  405. + }
  406. /* Perform whatever substitutions on the operands we are supposed
  407. to make due to commutativity or replacement of registers
  408. --- gcc/testsuite/gcc.dg/20011024-1.c.jj Thu Aug 30 22:30:55 2001
  409. +++ gcc/testsuite/gcc.dg/20011024-1.c Fri Oct 19 18:33:49 2001
  410. @@ -0,0 +1,264 @@
  411. +/* { dg-do run { target i?86-*-* } } */
  412. +/* { dg-options "-O2 -fomit-frame-pointer -march=i686" } */
  413. +
  414. +typedef struct {
  415. + void *s1a;
  416. +} s1;
  417. +typedef struct {
  418. + unsigned int s2a;
  419. + unsigned long long s2b;
  420. + unsigned int s2c;
  421. + unsigned int s2d;
  422. + unsigned short s2e;
  423. + unsigned char s2f;
  424. + s1 *s2g;
  425. + unsigned char s2h;
  426. +} s2;
  427. +typedef struct
  428. +{
  429. + unsigned int s3a;
  430. + unsigned int s3b;
  431. + unsigned int s3c;
  432. + unsigned int s3d;
  433. + unsigned int s3e[2];
  434. + unsigned int s3f[3];
  435. + unsigned int s3g;
  436. + unsigned int s3h;
  437. + unsigned int s3i;
  438. + unsigned int s3j;
  439. + unsigned int s3k;
  440. +} s3;
  441. +typedef struct
  442. +{
  443. + unsigned int s4a;
  444. + unsigned int s4b;
  445. + unsigned int s4c;
  446. + unsigned int s4d;
  447. + unsigned int s4e;
  448. + unsigned int s4f;
  449. + unsigned int s4g;
  450. + unsigned int s4h;
  451. + unsigned int s4i;
  452. + unsigned int s4j;
  453. + unsigned int s4k[64];
  454. +} s4;
  455. +typedef struct
  456. +{
  457. + unsigned int s5a;
  458. + unsigned int s5b;
  459. +} s5;
  460. +typedef struct
  461. +{
  462. + unsigned int s6a;
  463. + unsigned short s6b;
  464. + unsigned short s6c;
  465. + unsigned int s6d;
  466. + unsigned int s6e;
  467. +} s6;
  468. +typedef struct
  469. +{
  470. + unsigned long long s7a;
  471. + unsigned int s7b;
  472. +} s7;
  473. +
  474. +char buffer[1024];
  475. +
  476. +void f1 (void *x, int y, unsigned int z)
  477. +{
  478. +}
  479. +
  480. +static inline const unsigned int f2 (unsigned int x)
  481. +{
  482. + asm("" : "=r" (x) : "0" (x));
  483. + return x;
  484. +}
  485. +
  486. +int f3 (s2 *x, void *y, long long z, s1 **p)
  487. +{
  488. + return 0;
  489. +}
  490. +
  491. +void *f4(s2 *x, unsigned int y)
  492. +{
  493. + return 0;
  494. +}
  495. +
  496. +int f5(void *x)
  497. +{
  498. + return 0;
  499. +}
  500. +
  501. +int f6(s2 *x, s1 *y)
  502. +{
  503. + static int i;
  504. +
  505. + return i++;
  506. +}
  507. +
  508. +s1 *foo (void *x, long long y, unsigned int z, int v)
  509. +{
  510. + static s1 a;
  511. + static int b;
  512. +
  513. + if (v != 0x2204 || x != buffer)
  514. + abort ();
  515. + if (y != 0x2c5e780000000200LL + b)
  516. + abort ();
  517. + b += 0x200;
  518. + a.s1a = (char *) x + 32;
  519. + return &a;
  520. +}
  521. +
  522. +int test (s2 *x, s7 *y)
  523. +{
  524. + s1 *v1;
  525. + s3 *v3;
  526. + s4 *v4;
  527. + s5 *v5;
  528. + s6 *v6;
  529. + unsigned int a, b, c;
  530. + int d, e, f, g, h, i;
  531. + unsigned int j, k;
  532. + unsigned long long l, m, n;
  533. + void *o;
  534. +
  535. + l = y->s7a;
  536. + h = y->s7b;
  537. + f = h - x->s2f;
  538. + g = f3 (x, x->s2g, (l << x->s2h) - 1, &v1);
  539. + if (g)
  540. + return g;
  541. +
  542. + m = l;
  543. + j = m + 1;
  544. + m = y->s7a - x->s2b;
  545. + k = x->s2d;
  546. + o = f4 (x, 14);
  547. + g = f5 (o);
  548. + if (g)
  549. + return g;
  550. +
  551. + i = ((unsigned long long) x->s2e + 511) >> 9;
  552. + d = x->s2a;
  553. +
  554. + n = 0;
  555. + for (a = j - 1; a >= k; a--, m -= b) {
  556. + v1 = foo (x->s2g->s1a,
  557. + ((((unsigned long long) a * x->s2c) << x->s2h) + 1LL) << 9,
  558. + i << 9, 0x2204);
  559. + v3 = (s3 *)v1->s1a;
  560. + f1 (v3, 0, x->s2e);
  561. + v3->s3a = 0x58414746;
  562. + v3->s3a = f2 (v3->s3a);
  563. + v3->s3b = 1;
  564. + v3->s3b = f2 (v3->s3b);
  565. + v3->s3c = a;
  566. + v3->s3c = f2 (v3->s3c);
  567. + if (a == j - 1)
  568. + b = l - a * (unsigned long long) x->s2c;
  569. + else
  570. + b = x->s2c;
  571. + v3->s3d = b;
  572. + v3->s3d = f2 (v3->s3d);
  573. + v3->s3e[0] = (3LL >> x->s2h) + 1;
  574. + v3->s3e[0] = f2 (v3->s3e[0]);
  575. + v3->s3e[1] = (3LL >> x->s2h) + 2;
  576. + v3->s3e[1] = f2 (v3->s3e[1]);
  577. + v3->s3f[0] = 1;
  578. + v3->s3f[0] = f2 (v3->s3f[0]);
  579. + v3->s3f[1] = 1;
  580. + v3->s3f[1] = f2 (v3->s3f[1]);
  581. + v3->s3g = 0;
  582. + v3->s3g = f2 (v3->s3g);
  583. + v3->s3h = 512 / sizeof (unsigned int) - 1;
  584. + v3->s3h = f2 (v3->s3h);
  585. + v3->s3i = 0;
  586. + v3->s3i = f2 (v3->s3i);
  587. + c = b - ((unsigned int) (3LL >> x->s2h)) - 4;
  588. + v3->s3j = c;
  589. + v3->s3j = f2 (v3->s3j);
  590. + v3->s3k = c;
  591. + v3->s3k = f2 (v3->s3k);
  592. + g = f6 (x, v1);
  593. + if (g)
  594. + goto l0;
  595. +
  596. + v1 = foo (x->s2g->s1a,
  597. + ((((unsigned long long) a * x->s2c) << x->s2h) + 2LL) << 9,
  598. + i << 9, 0x2204);
  599. + v4 = (s4 *)v1->s1a;
  600. + f1 (v4, 0, x->s2e);
  601. + v4->s4a = 0x58414749;
  602. + v4->s4a = f2 (v4->s4a);
  603. + v4->s4b = 1;
  604. + v4->s4b = f2 (v4->s4b);
  605. + v4->s4c = a;
  606. + v4->s4c = f2 (v4->s4c);
  607. + v4->s4d = b;
  608. + v4->s4d = f2 (v4->s4d);
  609. + v4->s4e = 0;
  610. + v4->s4e = f2 (v4->s4e);
  611. + v4->s4f = (3LL >> x->s2h) + 3;
  612. + v4->s4f = f2 (v4->s4f);
  613. + v4->s4g = 1;
  614. + v4->s4g = f2 (v4->s4g);
  615. + v4->s4h = 0;
  616. + v4->s4h = f2 (v4->s4h);
  617. + v4->s4i = -1;
  618. + v4->s4i = f2 (v4->s4i);
  619. + v4->s4j = -1;
  620. + v4->s4j = f2 (v4->s4j);
  621. + for (e = 0; e < 64; e++)
  622. + {
  623. + v4->s4k[e] = -1;
  624. + v4->s4k[e] = f2 (v4->s4k[e]);
  625. + }
  626. + g = f6 (x, v1);
  627. + if (g)
  628. + goto l0;
  629. +
  630. + v1 = foo (x->s2g->s1a,
  631. + (((unsigned long long) a * x->s2c
  632. + + (unsigned int) ((3LL >> x->s2h) + 1)) << x->s2h) << 9,
  633. + (((unsigned long long) d + 511) >> 9) << 9, 0x2204);
  634. + v6 = (s6 *)v1->s1a;
  635. + f1 (v6, 0, d);
  636. + v6->s6a = 0x41425442;
  637. + v6->s6a = f2 (v6->s6a);
  638. + v6->s6b = 0;
  639. + v6->s6b = f2 (v6->s6b);
  640. + v6->s6c = 1;
  641. + v6->s6c = f2 (v6->s6c);
  642. + v6->s6d = -1;
  643. + v6->s6d = f2 (v6->s6d);
  644. + v6->s6e = -1;
  645. + v6->s6e = f2 (v6->s6e);
  646. + v5 = (s5 *) ((char *) v6 + 24);
  647. + v5->s5a = (3LL >> x->s2h) + 4;
  648. + v5->s5a = f2 (v5->s5a);
  649. + v5->s5b = b - v5->s5a;
  650. + g = f6 (x, v1);
  651. + if (g)
  652. + goto l0;
  653. + }
  654. + return 0;
  655. +
  656. +l0:
  657. + return g;
  658. +}
  659. +
  660. +s2 a;
  661. +s7 b;
  662. +s1 c;
  663. +
  664. +int main (void)
  665. +{
  666. + b.s7a = 66;
  667. + a.s2c = 0xabcdef;
  668. + a.s2g = &c;
  669. + a.s2h = 33;
  670. + c.s1a = buffer;
  671. + if (test (&a, &b) != 1)
  672. + abort ();
  673. + exit (0);
  674. +}