jsimd.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721
  1. /*
  2. * jsimd_arm.c
  3. *
  4. * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
  5. * Copyright (C) 2011, Nokia Corporation and/or its subsidiary(-ies).
  6. * Copyright (C) 2009-2011, 2013-2014, 2016, 2018, D. R. Commander.
  7. * Copyright (C) 2015-2016, 2018, Matthieu Darbois.
  8. * Copyright (C) 2019, Google LLC.
  9. *
  10. * Based on the x86 SIMD extension for IJG JPEG library,
  11. * Copyright (C) 1999-2006, MIYASAKA Masaru.
  12. * For conditions of distribution and use, see copyright notice in jsimdext.inc
  13. *
  14. * This file contains the interface between the "normal" portions
  15. * of the library and the SIMD implementations when running on a
  16. * 32-bit ARM architecture.
  17. */
  18. #define JPEG_INTERNALS
  19. #include "../../jinclude.h"
  20. #include "../../jpeglib.h"
  21. #include "../../jsimd.h"
  22. #include "../../jdct.h"
  23. #include "../../jsimddct.h"
  24. #include "../jsimd.h"
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <ctype.h>
  28. static unsigned int simd_support = ~0;
  29. static unsigned int simd_huffman = 1;
  30. #if !defined(__ARM_NEON__) && (defined(__linux__) || defined(ANDROID) || defined(__ANDROID__))
  31. #define SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT (1024 * 1024)
  32. LOCAL(int)
  33. check_feature(char *buffer, char *feature)
  34. {
  35. char *p;
  36. if (*feature == 0)
  37. return 0;
  38. if (strncmp(buffer, "Features", 8) != 0)
  39. return 0;
  40. buffer += 8;
  41. while (isspace(*buffer))
  42. buffer++;
  43. /* Check if 'feature' is present in the buffer as a separate word */
  44. while ((p = strstr(buffer, feature))) {
  45. if (p > buffer && !isspace(*(p - 1))) {
  46. buffer++;
  47. continue;
  48. }
  49. p += strlen(feature);
  50. if (*p != 0 && !isspace(*p)) {
  51. buffer++;
  52. continue;
  53. }
  54. return 1;
  55. }
  56. return 0;
  57. }
  58. LOCAL(int)
  59. parse_proc_cpuinfo(int bufsize)
  60. {
  61. char *buffer = (char *)malloc(bufsize);
  62. FILE *fd;
  63. simd_support = 0;
  64. if (!buffer)
  65. return 0;
  66. fd = fopen("/proc/cpuinfo", "r");
  67. if (fd) {
  68. while (fgets(buffer, bufsize, fd)) {
  69. if (!strchr(buffer, '\n') && !feof(fd)) {
  70. /* "impossible" happened - insufficient size of the buffer! */
  71. fclose(fd);
  72. free(buffer);
  73. return 0;
  74. }
  75. if (check_feature(buffer, "neon"))
  76. simd_support |= JSIMD_NEON;
  77. }
  78. fclose(fd);
  79. }
  80. free(buffer);
  81. return 1;
  82. }
  83. #endif
  84. /*
  85. * Check what SIMD accelerations are supported.
  86. *
  87. * FIXME: This code is racy under a multi-threaded environment.
  88. */
  89. LOCAL(void)
  90. init_simd(void)
  91. {
  92. #ifndef NO_GETENV
  93. char *env = NULL;
  94. #endif
  95. #if !defined(__ARM_NEON__) && (defined(__linux__) || defined(ANDROID) || defined(__ANDROID__))
  96. int bufsize = 1024; /* an initial guess for the line buffer size limit */
  97. #endif
  98. if (simd_support != ~0U)
  99. return;
  100. simd_support = 0;
  101. #if defined(__ARM_NEON__)
  102. simd_support |= JSIMD_NEON;
  103. #elif defined(__linux__) || defined(ANDROID) || defined(__ANDROID__)
  104. /* We still have a chance to use NEON regardless of globally used
  105. * -mcpu/-mfpu options passed to gcc by performing runtime detection via
  106. * /proc/cpuinfo parsing on linux/android */
  107. while (!parse_proc_cpuinfo(bufsize)) {
  108. bufsize *= 2;
  109. if (bufsize > SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT)
  110. break;
  111. }
  112. #endif
  113. #ifndef NO_GETENV
  114. /* Force different settings through environment variables */
  115. env = getenv("JSIMD_FORCENEON");
  116. if ((env != NULL) && (strcmp(env, "1") == 0))
  117. simd_support = JSIMD_NEON;
  118. env = getenv("JSIMD_FORCENONE");
  119. if ((env != NULL) && (strcmp(env, "1") == 0))
  120. simd_support = 0;
  121. env = getenv("JSIMD_NOHUFFENC");
  122. if ((env != NULL) && (strcmp(env, "1") == 0))
  123. simd_huffman = 0;
  124. #endif
  125. }
  126. GLOBAL(int)
  127. jsimd_can_rgb_ycc(void)
  128. {
  129. init_simd();
  130. /* The code is optimised for these values only */
  131. if (BITS_IN_JSAMPLE != 8)
  132. return 0;
  133. if (sizeof(JDIMENSION) != 4)
  134. return 0;
  135. if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
  136. return 0;
  137. if (simd_support & JSIMD_NEON)
  138. return 1;
  139. return 0;
  140. }
  141. GLOBAL(int)
  142. jsimd_can_rgb_gray(void)
  143. {
  144. return 0;
  145. }
  146. GLOBAL(int)
  147. jsimd_can_ycc_rgb(void)
  148. {
  149. init_simd();
  150. /* The code is optimised for these values only */
  151. if (BITS_IN_JSAMPLE != 8)
  152. return 0;
  153. if (sizeof(JDIMENSION) != 4)
  154. return 0;
  155. if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
  156. return 0;
  157. if (simd_support & JSIMD_NEON)
  158. return 1;
  159. return 0;
  160. }
  161. GLOBAL(int)
  162. jsimd_can_ycc_rgb565(void)
  163. {
  164. init_simd();
  165. /* The code is optimised for these values only */
  166. if (BITS_IN_JSAMPLE != 8)
  167. return 0;
  168. if (sizeof(JDIMENSION) != 4)
  169. return 0;
  170. if (simd_support & JSIMD_NEON)
  171. return 1;
  172. return 0;
  173. }
  174. GLOBAL(void)
  175. jsimd_rgb_ycc_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
  176. JSAMPIMAGE output_buf, JDIMENSION output_row,
  177. int num_rows)
  178. {
  179. void (*neonfct) (JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
  180. switch (cinfo->in_color_space) {
  181. case JCS_EXT_RGB:
  182. neonfct = jsimd_extrgb_ycc_convert_neon;
  183. break;
  184. case JCS_EXT_RGBX:
  185. case JCS_EXT_RGBA:
  186. neonfct = jsimd_extrgbx_ycc_convert_neon;
  187. break;
  188. case JCS_EXT_BGR:
  189. neonfct = jsimd_extbgr_ycc_convert_neon;
  190. break;
  191. case JCS_EXT_BGRX:
  192. case JCS_EXT_BGRA:
  193. neonfct = jsimd_extbgrx_ycc_convert_neon;
  194. break;
  195. case JCS_EXT_XBGR:
  196. case JCS_EXT_ABGR:
  197. neonfct = jsimd_extxbgr_ycc_convert_neon;
  198. break;
  199. case JCS_EXT_XRGB:
  200. case JCS_EXT_ARGB:
  201. neonfct = jsimd_extxrgb_ycc_convert_neon;
  202. break;
  203. default:
  204. neonfct = jsimd_extrgb_ycc_convert_neon;
  205. break;
  206. }
  207. neonfct(cinfo->image_width, input_buf, output_buf, output_row, num_rows);
  208. }
  209. GLOBAL(void)
  210. jsimd_rgb_gray_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
  211. JSAMPIMAGE output_buf, JDIMENSION output_row,
  212. int num_rows)
  213. {
  214. }
  215. GLOBAL(void)
  216. jsimd_ycc_rgb_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
  217. JDIMENSION input_row, JSAMPARRAY output_buf,
  218. int num_rows)
  219. {
  220. void (*neonfct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY, int);
  221. switch (cinfo->out_color_space) {
  222. case JCS_EXT_RGB:
  223. neonfct = jsimd_ycc_extrgb_convert_neon;
  224. break;
  225. case JCS_EXT_RGBX:
  226. case JCS_EXT_RGBA:
  227. neonfct = jsimd_ycc_extrgbx_convert_neon;
  228. break;
  229. case JCS_EXT_BGR:
  230. neonfct = jsimd_ycc_extbgr_convert_neon;
  231. break;
  232. case JCS_EXT_BGRX:
  233. case JCS_EXT_BGRA:
  234. neonfct = jsimd_ycc_extbgrx_convert_neon;
  235. break;
  236. case JCS_EXT_XBGR:
  237. case JCS_EXT_ABGR:
  238. neonfct = jsimd_ycc_extxbgr_convert_neon;
  239. break;
  240. case JCS_EXT_XRGB:
  241. case JCS_EXT_ARGB:
  242. neonfct = jsimd_ycc_extxrgb_convert_neon;
  243. break;
  244. default:
  245. neonfct = jsimd_ycc_extrgb_convert_neon;
  246. break;
  247. }
  248. neonfct(cinfo->output_width, input_buf, input_row, output_buf, num_rows);
  249. }
  250. GLOBAL(void)
  251. jsimd_ycc_rgb565_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
  252. JDIMENSION input_row, JSAMPARRAY output_buf,
  253. int num_rows)
  254. {
  255. jsimd_ycc_rgb565_convert_neon(cinfo->output_width, input_buf, input_row,
  256. output_buf, num_rows);
  257. }
  258. GLOBAL(int)
  259. jsimd_can_h2v2_downsample(void)
  260. {
  261. return 0;
  262. }
  263. GLOBAL(int)
  264. jsimd_can_h2v1_downsample(void)
  265. {
  266. return 0;
  267. }
  268. GLOBAL(void)
  269. jsimd_h2v2_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
  270. JSAMPARRAY input_data, JSAMPARRAY output_data)
  271. {
  272. }
  273. GLOBAL(void)
  274. jsimd_h2v1_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
  275. JSAMPARRAY input_data, JSAMPARRAY output_data)
  276. {
  277. }
  278. GLOBAL(int)
  279. jsimd_can_h2v2_upsample(void)
  280. {
  281. return 0;
  282. }
  283. GLOBAL(int)
  284. jsimd_can_h2v1_upsample(void)
  285. {
  286. return 0;
  287. }
  288. GLOBAL(void)
  289. jsimd_h2v2_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
  290. JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
  291. {
  292. }
  293. GLOBAL(void)
  294. jsimd_h2v1_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
  295. JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
  296. {
  297. }
  298. GLOBAL(int)
  299. jsimd_can_h2v2_fancy_upsample(void)
  300. {
  301. return 0;
  302. }
  303. GLOBAL(int)
  304. jsimd_can_h2v1_fancy_upsample(void)
  305. {
  306. init_simd();
  307. /* The code is optimised for these values only */
  308. if (BITS_IN_JSAMPLE != 8)
  309. return 0;
  310. if (sizeof(JDIMENSION) != 4)
  311. return 0;
  312. if (simd_support & JSIMD_NEON)
  313. return 1;
  314. return 0;
  315. }
  316. GLOBAL(void)
  317. jsimd_h2v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
  318. JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
  319. {
  320. }
  321. GLOBAL(void)
  322. jsimd_h2v1_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
  323. JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
  324. {
  325. jsimd_h2v1_fancy_upsample_neon(cinfo->max_v_samp_factor,
  326. compptr->downsampled_width, input_data,
  327. output_data_ptr);
  328. }
  329. GLOBAL(int)
  330. jsimd_can_h2v2_merged_upsample(void)
  331. {
  332. return 0;
  333. }
  334. GLOBAL(int)
  335. jsimd_can_h2v1_merged_upsample(void)
  336. {
  337. return 0;
  338. }
  339. GLOBAL(void)
  340. jsimd_h2v2_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
  341. JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
  342. {
  343. }
  344. GLOBAL(void)
  345. jsimd_h2v1_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
  346. JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
  347. {
  348. }
  349. GLOBAL(int)
  350. jsimd_can_convsamp(void)
  351. {
  352. init_simd();
  353. /* The code is optimised for these values only */
  354. if (DCTSIZE != 8)
  355. return 0;
  356. if (BITS_IN_JSAMPLE != 8)
  357. return 0;
  358. if (sizeof(JDIMENSION) != 4)
  359. return 0;
  360. if (sizeof(DCTELEM) != 2)
  361. return 0;
  362. if (simd_support & JSIMD_NEON)
  363. return 1;
  364. return 0;
  365. }
  366. GLOBAL(int)
  367. jsimd_can_convsamp_float(void)
  368. {
  369. return 0;
  370. }
  371. GLOBAL(void)
  372. jsimd_convsamp(JSAMPARRAY sample_data, JDIMENSION start_col,
  373. DCTELEM *workspace)
  374. {
  375. jsimd_convsamp_neon(sample_data, start_col, workspace);
  376. }
  377. GLOBAL(void)
  378. jsimd_convsamp_float(JSAMPARRAY sample_data, JDIMENSION start_col,
  379. FAST_FLOAT *workspace)
  380. {
  381. }
  382. GLOBAL(int)
  383. jsimd_can_fdct_islow(void)
  384. {
  385. return 0;
  386. }
  387. GLOBAL(int)
  388. jsimd_can_fdct_ifast(void)
  389. {
  390. init_simd();
  391. /* The code is optimised for these values only */
  392. if (DCTSIZE != 8)
  393. return 0;
  394. if (sizeof(DCTELEM) != 2)
  395. return 0;
  396. if (simd_support & JSIMD_NEON)
  397. return 1;
  398. return 0;
  399. }
  400. GLOBAL(int)
  401. jsimd_can_fdct_float(void)
  402. {
  403. return 0;
  404. }
  405. GLOBAL(void)
  406. jsimd_fdct_islow(DCTELEM *data)
  407. {
  408. }
  409. GLOBAL(void)
  410. jsimd_fdct_ifast(DCTELEM *data)
  411. {
  412. jsimd_fdct_ifast_neon(data);
  413. }
  414. GLOBAL(void)
  415. jsimd_fdct_float(FAST_FLOAT *data)
  416. {
  417. }
  418. GLOBAL(int)
  419. jsimd_can_quantize(void)
  420. {
  421. init_simd();
  422. /* The code is optimised for these values only */
  423. if (DCTSIZE != 8)
  424. return 0;
  425. if (sizeof(JCOEF) != 2)
  426. return 0;
  427. if (sizeof(DCTELEM) != 2)
  428. return 0;
  429. if (simd_support & JSIMD_NEON)
  430. return 1;
  431. return 0;
  432. }
  433. GLOBAL(int)
  434. jsimd_can_quantize_float(void)
  435. {
  436. return 0;
  437. }
  438. GLOBAL(void)
  439. jsimd_quantize(JCOEFPTR coef_block, DCTELEM *divisors, DCTELEM *workspace)
  440. {
  441. jsimd_quantize_neon(coef_block, divisors, workspace);
  442. }
  443. GLOBAL(void)
  444. jsimd_quantize_float(JCOEFPTR coef_block, FAST_FLOAT *divisors,
  445. FAST_FLOAT *workspace)
  446. {
  447. }
  448. GLOBAL(int)
  449. jsimd_can_idct_2x2(void)
  450. {
  451. init_simd();
  452. /* The code is optimised for these values only */
  453. if (DCTSIZE != 8)
  454. return 0;
  455. if (sizeof(JCOEF) != 2)
  456. return 0;
  457. if (BITS_IN_JSAMPLE != 8)
  458. return 0;
  459. if (sizeof(JDIMENSION) != 4)
  460. return 0;
  461. if (sizeof(ISLOW_MULT_TYPE) != 2)
  462. return 0;
  463. if (simd_support & JSIMD_NEON)
  464. return 1;
  465. return 0;
  466. }
  467. GLOBAL(int)
  468. jsimd_can_idct_4x4(void)
  469. {
  470. init_simd();
  471. /* The code is optimised for these values only */
  472. if (DCTSIZE != 8)
  473. return 0;
  474. if (sizeof(JCOEF) != 2)
  475. return 0;
  476. if (BITS_IN_JSAMPLE != 8)
  477. return 0;
  478. if (sizeof(JDIMENSION) != 4)
  479. return 0;
  480. if (sizeof(ISLOW_MULT_TYPE) != 2)
  481. return 0;
  482. if (simd_support & JSIMD_NEON)
  483. return 1;
  484. return 0;
  485. }
  486. GLOBAL(void)
  487. jsimd_idct_2x2(j_decompress_ptr cinfo, jpeg_component_info *compptr,
  488. JCOEFPTR coef_block, JSAMPARRAY output_buf,
  489. JDIMENSION output_col)
  490. {
  491. jsimd_idct_2x2_neon(compptr->dct_table, coef_block, output_buf, output_col);
  492. }
  493. GLOBAL(void)
  494. jsimd_idct_4x4(j_decompress_ptr cinfo, jpeg_component_info *compptr,
  495. JCOEFPTR coef_block, JSAMPARRAY output_buf,
  496. JDIMENSION output_col)
  497. {
  498. jsimd_idct_4x4_neon(compptr->dct_table, coef_block, output_buf, output_col);
  499. }
  500. GLOBAL(int)
  501. jsimd_can_idct_islow(void)
  502. {
  503. init_simd();
  504. /* The code is optimised for these values only */
  505. if (DCTSIZE != 8)
  506. return 0;
  507. if (sizeof(JCOEF) != 2)
  508. return 0;
  509. if (BITS_IN_JSAMPLE != 8)
  510. return 0;
  511. if (sizeof(JDIMENSION) != 4)
  512. return 0;
  513. if (sizeof(ISLOW_MULT_TYPE) != 2)
  514. return 0;
  515. if (simd_support & JSIMD_NEON)
  516. return 1;
  517. return 0;
  518. }
  519. GLOBAL(int)
  520. jsimd_can_idct_ifast(void)
  521. {
  522. init_simd();
  523. /* The code is optimised for these values only */
  524. if (DCTSIZE != 8)
  525. return 0;
  526. if (sizeof(JCOEF) != 2)
  527. return 0;
  528. if (BITS_IN_JSAMPLE != 8)
  529. return 0;
  530. if (sizeof(JDIMENSION) != 4)
  531. return 0;
  532. if (sizeof(IFAST_MULT_TYPE) != 2)
  533. return 0;
  534. if (IFAST_SCALE_BITS != 2)
  535. return 0;
  536. if (simd_support & JSIMD_NEON)
  537. return 1;
  538. return 0;
  539. }
  540. GLOBAL(int)
  541. jsimd_can_idct_float(void)
  542. {
  543. return 0;
  544. }
  545. GLOBAL(void)
  546. jsimd_idct_islow(j_decompress_ptr cinfo, jpeg_component_info *compptr,
  547. JCOEFPTR coef_block, JSAMPARRAY output_buf,
  548. JDIMENSION output_col)
  549. {
  550. jsimd_idct_islow_neon(compptr->dct_table, coef_block, output_buf,
  551. output_col);
  552. }
  553. GLOBAL(void)
  554. jsimd_idct_ifast(j_decompress_ptr cinfo, jpeg_component_info *compptr,
  555. JCOEFPTR coef_block, JSAMPARRAY output_buf,
  556. JDIMENSION output_col)
  557. {
  558. jsimd_idct_ifast_neon(compptr->dct_table, coef_block, output_buf,
  559. output_col);
  560. }
  561. GLOBAL(void)
  562. jsimd_idct_float(j_decompress_ptr cinfo, jpeg_component_info *compptr,
  563. JCOEFPTR coef_block, JSAMPARRAY output_buf,
  564. JDIMENSION output_col)
  565. {
  566. }
  567. GLOBAL(int)
  568. jsimd_can_huff_encode_one_block(void)
  569. {
  570. init_simd();
  571. if (DCTSIZE != 8)
  572. return 0;
  573. if (sizeof(JCOEF) != 2)
  574. return 0;
  575. if (simd_support & JSIMD_NEON && simd_huffman)
  576. return 1;
  577. return 0;
  578. }
  579. GLOBAL(JOCTET *)
  580. jsimd_huff_encode_one_block(void *state, JOCTET *buffer, JCOEFPTR block,
  581. int last_dc_val, c_derived_tbl *dctbl,
  582. c_derived_tbl *actbl)
  583. {
  584. return jsimd_huff_encode_one_block_neon(state, buffer, block, last_dc_val,
  585. dctbl, actbl);
  586. }
  587. GLOBAL(int)
  588. jsimd_can_encode_mcu_AC_first_prepare(void)
  589. {
  590. return 0;
  591. }
  592. GLOBAL(void)
  593. jsimd_encode_mcu_AC_first_prepare(const JCOEF *block,
  594. const int *jpeg_natural_order_start, int Sl,
  595. int Al, JCOEF *values, size_t *zerobits)
  596. {
  597. }
  598. GLOBAL(int)
  599. jsimd_can_encode_mcu_AC_refine_prepare(void)
  600. {
  601. return 0;
  602. }
  603. GLOBAL(int)
  604. jsimd_encode_mcu_AC_refine_prepare(const JCOEF *block,
  605. const int *jpeg_natural_order_start, int Sl,
  606. int Al, JCOEF *absvalues, size_t *bits)
  607. {
  608. return 0;
  609. }