1 /* Printing operations with very long integers. 2 Copyright (C) 2012-2018 Free Software Foundation, Inc. 3 Contributed by Kenneth Zadeck <zadeck@naturalbridge.com> 4 5 This file is part of GCC. 6 7 GCC is free software; you can redistribute it and/or modify it 8 under the terms of the GNU General Public License as published by the 9 Free Software Foundation; either version 3, or (at your option) any 10 later version. 11 12 GCC is distributed in the hope that it will be useful, but WITHOUT 13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with GCC; see the file COPYING3. If not see 19 <http://www.gnu.org/licenses/>. */ 20 21 #include "config.h" 22 #include "system.h" 23 #include "coretypes.h" 24 25 /* 26 * public printing routines. 27 */ 28 29 #define BLOCKS_NEEDED(PREC) \ 30 (((PREC) + HOST_BITS_PER_WIDE_INT - 1) / HOST_BITS_PER_WIDE_INT) 31 32 void 33 print_dec (const wide_int_ref &wi, char *buf, signop sgn) 34 { 35 if (sgn == SIGNED) 36 print_decs (wi, buf); 37 else 38 print_decu (wi, buf); 39 } 40 41 void 42 print_dec (const wide_int_ref &wi, FILE *file, signop sgn) 43 { 44 if (sgn == SIGNED) 45 print_decs (wi, file); 46 else 47 print_decu (wi, file); 48 } 49 50 51 /* Try to print the signed self in decimal to BUF if the number fits 52 in a HWI. Other print in hex. */ 53 54 void 55 print_decs (const wide_int_ref &wi, char *buf) 56 { 57 if ((wi.get_precision () <= HOST_BITS_PER_WIDE_INT) 58 || (wi.get_len () == 1)) 59 { 60 if (wi::neg_p (wi)) 61 sprintf (buf, "-" HOST_WIDE_INT_PRINT_UNSIGNED, 62 -(unsigned HOST_WIDE_INT) wi.to_shwi ()); 63 else 64 sprintf (buf, HOST_WIDE_INT_PRINT_DEC, wi.to_shwi ()); 65 } 66 else 67 print_hex (wi, buf); 68 } 69 70 /* Try to print the signed self in decimal to FILE if the number fits 71 in a HWI. Other print in hex. */ 72 73 void 74 print_decs (const wide_int_ref &wi, FILE *file) 75 { 76 char buf[WIDE_INT_PRINT_BUFFER_SIZE]; 77 print_decs (wi, buf); 78 fputs (buf, file); 79 } 80 81 /* Try to print the unsigned self in decimal to BUF if the number fits 82 in a HWI. Other print in hex. */ 83 84 void 85 print_decu (const wide_int_ref &wi, char *buf) 86 { 87 if ((wi.get_precision () <= HOST_BITS_PER_WIDE_INT) 88 || (wi.get_len () == 1 && !wi::neg_p (wi))) 89 sprintf (buf, HOST_WIDE_INT_PRINT_UNSIGNED, wi.to_uhwi ()); 90 else 91 print_hex (wi, buf); 92 } 93 94 /* Try to print the signed self in decimal to FILE if the number fits 95 in a HWI. Other print in hex. */ 96 97 void 98 print_decu (const wide_int_ref &wi, FILE *file) 99 { 100 char buf[WIDE_INT_PRINT_BUFFER_SIZE]; 101 print_decu (wi, buf); 102 fputs (buf, file); 103 } 104 105 void 106 print_hex (const wide_int_ref &val, char *buf) 107 { 108 if (val == 0) 109 buf += sprintf (buf, "0x0"); 110 else 111 { 112 buf += sprintf (buf, "0x"); 113 int start = ROUND_DOWN (val.get_precision (), HOST_BITS_PER_WIDE_INT); 114 int width = val.get_precision () - start; 115 bool first_p = true; 116 for (int i = start; i >= 0; i -= HOST_BITS_PER_WIDE_INT) 117 { 118 unsigned HOST_WIDE_INT uhwi = wi::extract_uhwi (val, i, width); 119 if (!first_p) 120 buf += sprintf (buf, HOST_WIDE_INT_PRINT_PADDED_HEX, uhwi); 121 else if (uhwi != 0) 122 { 123 buf += sprintf (buf, HOST_WIDE_INT_PRINT_HEX_PURE, uhwi); 124 first_p = false; 125 } 126 width = HOST_BITS_PER_WIDE_INT; 127 } 128 } 129 } 130 131 /* Print one big hex number to FILE. Note that some assemblers may not 132 accept this for large modes. */ 133 void 134 print_hex (const wide_int_ref &wi, FILE *file) 135 { 136 char buf[WIDE_INT_PRINT_BUFFER_SIZE]; 137 print_hex (wi, buf); 138 fputs (buf, file); 139 } 140 141