xref: /netbsd-src/external/gpl3/binutils.old/dist/opcodes/loongarch-coder.c (revision c42dbd0ed2e61fe6eda8590caa852ccf34719964)
1*c42dbd0eSchristos /* LoongArch opcode support.
2*c42dbd0eSchristos    Copyright (C) 2021-2022 Free Software Foundation, Inc.
3*c42dbd0eSchristos    Contributed by Loongson Ltd.
4*c42dbd0eSchristos 
5*c42dbd0eSchristos    This file is part of the GNU opcodes library.
6*c42dbd0eSchristos 
7*c42dbd0eSchristos    This library is free software; you can redistribute it and/or modify
8*c42dbd0eSchristos    it under the terms of the GNU General Public License as published by
9*c42dbd0eSchristos    the Free Software Foundation; either version 3, or (at your option)
10*c42dbd0eSchristos    any later version.
11*c42dbd0eSchristos 
12*c42dbd0eSchristos    It is distributed in the hope that it will be useful, but WITHOUT
13*c42dbd0eSchristos    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14*c42dbd0eSchristos    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15*c42dbd0eSchristos    License for more details.
16*c42dbd0eSchristos 
17*c42dbd0eSchristos    You should have received a copy of the GNU General Public License
18*c42dbd0eSchristos    along with this program; see the file COPYING3.  If not,
19*c42dbd0eSchristos    see <http://www.gnu.org/licenses/>.  */
20*c42dbd0eSchristos #include "sysdep.h"
21*c42dbd0eSchristos #include "opcode/loongarch.h"
22*c42dbd0eSchristos 
23*c42dbd0eSchristos int
is_unsigned(const char * c_str)24*c42dbd0eSchristos is_unsigned (const char *c_str)
25*c42dbd0eSchristos {
26*c42dbd0eSchristos   if (c_str[0] == '0' && (c_str[1] == 'x' || c_str[1] == 'X'))
27*c42dbd0eSchristos     {
28*c42dbd0eSchristos       c_str += 2;
29*c42dbd0eSchristos       while (('a' <= *c_str && *c_str <= 'f')
30*c42dbd0eSchristos 	     || ('A' <= *c_str && *c_str <= 'F')
31*c42dbd0eSchristos 	     || ('0' <= *c_str && *c_str <= '9'))
32*c42dbd0eSchristos 	c_str++;
33*c42dbd0eSchristos     }
34*c42dbd0eSchristos   else if (*c_str == '\0')
35*c42dbd0eSchristos     return 0;
36*c42dbd0eSchristos   else
37*c42dbd0eSchristos     while ('0' <= *c_str && *c_str <= '9')
38*c42dbd0eSchristos       c_str++;
39*c42dbd0eSchristos   return *c_str == '\0';
40*c42dbd0eSchristos }
41*c42dbd0eSchristos 
42*c42dbd0eSchristos int
is_signed(const char * c_str)43*c42dbd0eSchristos is_signed (const char *c_str)
44*c42dbd0eSchristos {
45*c42dbd0eSchristos   return *c_str == '-' ? is_unsigned (c_str + 1) : is_unsigned (c_str);
46*c42dbd0eSchristos }
47*c42dbd0eSchristos 
48*c42dbd0eSchristos int
loongarch_get_bit_field_width(const char * bit_field,char ** end)49*c42dbd0eSchristos loongarch_get_bit_field_width (const char *bit_field, char **end)
50*c42dbd0eSchristos {
51*c42dbd0eSchristos   int width = 0;
52*c42dbd0eSchristos   char has_specify = 0, *bit_field_1 = (char *) bit_field;
53*c42dbd0eSchristos   if (bit_field_1 && *bit_field_1 != '\0')
54*c42dbd0eSchristos     while (1)
55*c42dbd0eSchristos       {
56*c42dbd0eSchristos 	strtol (bit_field_1, &bit_field_1, 10);
57*c42dbd0eSchristos 
58*c42dbd0eSchristos 	if (*bit_field_1 != ':')
59*c42dbd0eSchristos 	  break;
60*c42dbd0eSchristos 	bit_field_1++;
61*c42dbd0eSchristos 
62*c42dbd0eSchristos 	width += strtol (bit_field_1, &bit_field_1, 10);
63*c42dbd0eSchristos 	has_specify = 1;
64*c42dbd0eSchristos 
65*c42dbd0eSchristos 	if (*bit_field_1 != '|')
66*c42dbd0eSchristos 	  break;
67*c42dbd0eSchristos 	bit_field_1++;
68*c42dbd0eSchristos       }
69*c42dbd0eSchristos   if (end)
70*c42dbd0eSchristos     *end = bit_field_1;
71*c42dbd0eSchristos   return has_specify ? width : -1;
72*c42dbd0eSchristos }
73*c42dbd0eSchristos 
74*c42dbd0eSchristos int32_t
loongarch_decode_imm(const char * bit_field,insn_t insn,int si)75*c42dbd0eSchristos loongarch_decode_imm (const char *bit_field, insn_t insn, int si)
76*c42dbd0eSchristos {
77*c42dbd0eSchristos   int32_t ret = 0;
78*c42dbd0eSchristos   uint32_t t;
79*c42dbd0eSchristos   int len = 0, width, b_start;
80*c42dbd0eSchristos   char *bit_field_1 = (char *) bit_field;
81*c42dbd0eSchristos   while (1)
82*c42dbd0eSchristos     {
83*c42dbd0eSchristos       b_start = strtol (bit_field_1, &bit_field_1, 10);
84*c42dbd0eSchristos       if (*bit_field_1 != ':')
85*c42dbd0eSchristos 	break;
86*c42dbd0eSchristos       width = strtol (bit_field_1 + 1, &bit_field_1, 10);
87*c42dbd0eSchristos       len += width;
88*c42dbd0eSchristos 
89*c42dbd0eSchristos       t = insn;
90*c42dbd0eSchristos       t <<= sizeof (t) * 8 - width - b_start;
91*c42dbd0eSchristos       t >>= sizeof (t) * 8 - width;
92*c42dbd0eSchristos       ret <<= width;
93*c42dbd0eSchristos       ret |= t;
94*c42dbd0eSchristos 
95*c42dbd0eSchristos       if (*bit_field_1 != '|')
96*c42dbd0eSchristos 	break;
97*c42dbd0eSchristos       bit_field_1++;
98*c42dbd0eSchristos     }
99*c42dbd0eSchristos 
100*c42dbd0eSchristos   if (*bit_field_1 == '<' && *(++bit_field_1) == '<')
101*c42dbd0eSchristos     {
102*c42dbd0eSchristos       width = atoi (bit_field_1 + 1);
103*c42dbd0eSchristos       ret <<= width;
104*c42dbd0eSchristos       len += width;
105*c42dbd0eSchristos     }
106*c42dbd0eSchristos   else if (*bit_field_1 == '+')
107*c42dbd0eSchristos     ret += atoi (bit_field_1 + 1);
108*c42dbd0eSchristos 
109*c42dbd0eSchristos   /* Extend signed bit.  */
110*c42dbd0eSchristos   if (si)
111*c42dbd0eSchristos     {
112*c42dbd0eSchristos       uint32_t sign = 1u << (len - 1);
113*c42dbd0eSchristos       ret = (ret ^ sign) - sign;
114*c42dbd0eSchristos     }
115*c42dbd0eSchristos 
116*c42dbd0eSchristos   return ret;
117*c42dbd0eSchristos }
118*c42dbd0eSchristos 
119*c42dbd0eSchristos static insn_t
loongarch_encode_imm(const char * bit_field,int32_t imm)120*c42dbd0eSchristos loongarch_encode_imm (const char *bit_field, int32_t imm)
121*c42dbd0eSchristos {
122*c42dbd0eSchristos   char *bit_field_1 = (char *) bit_field;
123*c42dbd0eSchristos   char *t = bit_field_1;
124*c42dbd0eSchristos   int width, b_start;
125*c42dbd0eSchristos   insn_t ret = 0;
126*c42dbd0eSchristos   uint32_t i;
127*c42dbd0eSchristos   uint32_t uimm = (uint32_t)imm;
128*c42dbd0eSchristos 
129*c42dbd0eSchristos   width = loongarch_get_bit_field_width (t, &t);
130*c42dbd0eSchristos   if (width == -1)
131*c42dbd0eSchristos     return ret;
132*c42dbd0eSchristos 
133*c42dbd0eSchristos   if (*t == '<' && *(++t) == '<')
134*c42dbd0eSchristos     width += atoi (t + 1);
135*c42dbd0eSchristos   else if (*t == '+')
136*c42dbd0eSchristos     uimm -= atoi (t + 1);
137*c42dbd0eSchristos 
138*c42dbd0eSchristos   uimm = width ? (uimm << (sizeof (uimm) * 8 - width)) : 0;
139*c42dbd0eSchristos 
140*c42dbd0eSchristos   while (1)
141*c42dbd0eSchristos     {
142*c42dbd0eSchristos       b_start = strtol (bit_field_1, &bit_field_1, 10);
143*c42dbd0eSchristos       if (*bit_field_1 != ':')
144*c42dbd0eSchristos 	break;
145*c42dbd0eSchristos       width = strtol (bit_field_1 + 1, &bit_field_1, 10);
146*c42dbd0eSchristos       i = uimm;
147*c42dbd0eSchristos       i = width ? (i >> (sizeof (i) * 8 - width)) : 0;
148*c42dbd0eSchristos       i = (b_start == 32) ? 0 : (i << b_start);
149*c42dbd0eSchristos       ret |= i;
150*c42dbd0eSchristos       uimm = (width == 32) ? 0 : (uimm << width);
151*c42dbd0eSchristos 
152*c42dbd0eSchristos       if (*bit_field_1 != '|')
153*c42dbd0eSchristos 	break;
154*c42dbd0eSchristos       bit_field_1++;
155*c42dbd0eSchristos     }
156*c42dbd0eSchristos   return ret;
157*c42dbd0eSchristos }
158*c42dbd0eSchristos 
159*c42dbd0eSchristos /* Parse such FORMAT
160*c42dbd0eSchristos    ""
161*c42dbd0eSchristos    "u"
162*c42dbd0eSchristos    "v0:5,r5:5,s10:10<<2"
163*c42dbd0eSchristos    "r0:5,r5:5,r10:5,u15:2+1"
164*c42dbd0eSchristos    "r,r,u0:5+32,u0:5+1"
165*c42dbd0eSchristos */
166*c42dbd0eSchristos static int
loongarch_parse_format(const char * format,char * esc1s,char * esc2s,const char ** bit_fields)167*c42dbd0eSchristos loongarch_parse_format (const char *format, char *esc1s, char *esc2s,
168*c42dbd0eSchristos 			const char **bit_fields)
169*c42dbd0eSchristos {
170*c42dbd0eSchristos   size_t arg_num = 0;
171*c42dbd0eSchristos 
172*c42dbd0eSchristos   if (*format == '\0')
173*c42dbd0eSchristos     goto end;
174*c42dbd0eSchristos 
175*c42dbd0eSchristos   while (1)
176*c42dbd0eSchristos     {
177*c42dbd0eSchristos       /* esc1    esc2
178*c42dbd0eSchristos 	 for "[a-zA-Z][a-zA-Z]?"  */
179*c42dbd0eSchristos       if (('a' <= *format && *format <= 'z')
180*c42dbd0eSchristos 	  || ('A' <= *format && *format <= 'Z'))
181*c42dbd0eSchristos 	{
182*c42dbd0eSchristos 	  *esc1s++ = *format++;
183*c42dbd0eSchristos 	  if (('a' <= *format && *format <= 'z')
184*c42dbd0eSchristos 	      || ('A' <= *format && *format <= 'Z'))
185*c42dbd0eSchristos 	    *esc2s++ = *format++;
186*c42dbd0eSchristos 	  else
187*c42dbd0eSchristos 	    *esc2s++ = '\0';
188*c42dbd0eSchristos 	}
189*c42dbd0eSchristos       else
190*c42dbd0eSchristos 	return -1;
191*c42dbd0eSchristos 
192*c42dbd0eSchristos       arg_num++;
193*c42dbd0eSchristos       if (MAX_ARG_NUM_PLUS_2 - 2 < arg_num)
194*c42dbd0eSchristos 	/* Need larger MAX_ARG_NUM_PLUS_2.  */
195*c42dbd0eSchristos 	return -1;
196*c42dbd0eSchristos 
197*c42dbd0eSchristos       *bit_fields++ = format;
198*c42dbd0eSchristos 
199*c42dbd0eSchristos       if ('0' <= *format && *format <= '9')
200*c42dbd0eSchristos 	{
201*c42dbd0eSchristos 	  /* For "[0-9]+:[0-9]+(\|[0-9]+:[0-9]+)*".  */
202*c42dbd0eSchristos 	  while (1)
203*c42dbd0eSchristos 	    {
204*c42dbd0eSchristos 	      while ('0' <= *format && *format <= '9')
205*c42dbd0eSchristos 		format++;
206*c42dbd0eSchristos 
207*c42dbd0eSchristos 	      if (*format != ':')
208*c42dbd0eSchristos 		return -1;
209*c42dbd0eSchristos 	      format++;
210*c42dbd0eSchristos 
211*c42dbd0eSchristos 	      if (!('0' <= *format && *format <= '9'))
212*c42dbd0eSchristos 		return -1;
213*c42dbd0eSchristos 	      while ('0' <= *format && *format <= '9')
214*c42dbd0eSchristos 		format++;
215*c42dbd0eSchristos 
216*c42dbd0eSchristos 	      if (*format != '|')
217*c42dbd0eSchristos 		break;
218*c42dbd0eSchristos 	      format++;
219*c42dbd0eSchristos 	    }
220*c42dbd0eSchristos 
221*c42dbd0eSchristos 	  /* For "((\+|<<)[1-9][0-9]*)?".  */
222*c42dbd0eSchristos 	  do
223*c42dbd0eSchristos 	    {
224*c42dbd0eSchristos 	      if (*format == '+')
225*c42dbd0eSchristos 		format++;
226*c42dbd0eSchristos 	      else if (format[0] == '<' && format[1] == '<')
227*c42dbd0eSchristos 		format += 2;
228*c42dbd0eSchristos 	      else
229*c42dbd0eSchristos 		break;
230*c42dbd0eSchristos 
231*c42dbd0eSchristos 	      if (!('1' <= *format && *format <= '9'))
232*c42dbd0eSchristos 		return -1;
233*c42dbd0eSchristos 	      while ('0' <= *format && *format <= '9')
234*c42dbd0eSchristos 		format++;
235*c42dbd0eSchristos 	    }
236*c42dbd0eSchristos 	  while (0);
237*c42dbd0eSchristos 	}
238*c42dbd0eSchristos 
239*c42dbd0eSchristos       if (*format == ',')
240*c42dbd0eSchristos 	format++;
241*c42dbd0eSchristos       else if (*format == '\0')
242*c42dbd0eSchristos 	break;
243*c42dbd0eSchristos       else
244*c42dbd0eSchristos 	return -1;
245*c42dbd0eSchristos     }
246*c42dbd0eSchristos 
247*c42dbd0eSchristos  end:
248*c42dbd0eSchristos   *esc1s = '\0';
249*c42dbd0eSchristos   return 0;
250*c42dbd0eSchristos }
251*c42dbd0eSchristos 
252*c42dbd0eSchristos size_t
loongarch_split_args_by_comma(char * args,const char * arg_strs[])253*c42dbd0eSchristos loongarch_split_args_by_comma (char *args, const char *arg_strs[])
254*c42dbd0eSchristos {
255*c42dbd0eSchristos   size_t num = 0;
256*c42dbd0eSchristos 
257*c42dbd0eSchristos   if (*args)
258*c42dbd0eSchristos     arg_strs[num++] = args;
259*c42dbd0eSchristos   for (; *args; args++)
260*c42dbd0eSchristos     if (*args == ',')
261*c42dbd0eSchristos       {
262*c42dbd0eSchristos 	if (MAX_ARG_NUM_PLUS_2 - 1 == num)
263*c42dbd0eSchristos 	  break;
264*c42dbd0eSchristos 	else
265*c42dbd0eSchristos 	  *args = '\0', arg_strs[num++] = args + 1;
266*c42dbd0eSchristos       }
267*c42dbd0eSchristos   arg_strs[num] = NULL;
268*c42dbd0eSchristos   return num;
269*c42dbd0eSchristos }
270*c42dbd0eSchristos 
271*c42dbd0eSchristos char *
loongarch_cat_splited_strs(const char * arg_strs[])272*c42dbd0eSchristos loongarch_cat_splited_strs (const char *arg_strs[])
273*c42dbd0eSchristos {
274*c42dbd0eSchristos   char *ret;
275*c42dbd0eSchristos   size_t n, l;
276*c42dbd0eSchristos 
277*c42dbd0eSchristos   for (l = 0, n = 0; arg_strs[n]; n++)
278*c42dbd0eSchristos     l += strlen (arg_strs[n]);
279*c42dbd0eSchristos   ret = malloc (l + n + 1);
280*c42dbd0eSchristos   if (!ret)
281*c42dbd0eSchristos     return ret;
282*c42dbd0eSchristos 
283*c42dbd0eSchristos   ret[0] = '\0';
284*c42dbd0eSchristos   if (0 < n)
285*c42dbd0eSchristos     strcat (ret, arg_strs[0]);
286*c42dbd0eSchristos   for (l = 1; l < n; l++)
287*c42dbd0eSchristos     strcat (ret, ","), strcat (ret, arg_strs[l]);
288*c42dbd0eSchristos   return ret;
289*c42dbd0eSchristos }
290*c42dbd0eSchristos 
291*c42dbd0eSchristos insn_t
loongarch_foreach_args(const char * format,const char * arg_strs[],int32_t (* helper)(char esc1,char esc2,const char * bit_field,const char * arg,void * context),void * context)292*c42dbd0eSchristos loongarch_foreach_args (const char *format, const char *arg_strs[],
293*c42dbd0eSchristos 			int32_t (*helper) (char esc1, char esc2,
294*c42dbd0eSchristos 					   const char *bit_field,
295*c42dbd0eSchristos 					   const char *arg, void *context),
296*c42dbd0eSchristos 			void *context)
297*c42dbd0eSchristos {
298*c42dbd0eSchristos   char esc1s[MAX_ARG_NUM_PLUS_2 - 1], esc2s[MAX_ARG_NUM_PLUS_2 - 1];
299*c42dbd0eSchristos   const char *bit_fields[MAX_ARG_NUM_PLUS_2 - 1];
300*c42dbd0eSchristos   size_t i;
301*c42dbd0eSchristos   insn_t ret = 0;
302*c42dbd0eSchristos   int ok;
303*c42dbd0eSchristos 
304*c42dbd0eSchristos   ok = loongarch_parse_format (format, esc1s, esc2s, bit_fields) == 0;
305*c42dbd0eSchristos 
306*c42dbd0eSchristos   /* Make sure the num of actual args is equal to the num of escape.  */
307*c42dbd0eSchristos   for (i = 0; esc1s[i] && arg_strs[i]; i++)
308*c42dbd0eSchristos     ;
309*c42dbd0eSchristos   ok = ok && !esc1s[i] && !arg_strs[i];
310*c42dbd0eSchristos 
311*c42dbd0eSchristos   if (ok && helper)
312*c42dbd0eSchristos     {
313*c42dbd0eSchristos       for (i = 0; arg_strs[i]; i++)
314*c42dbd0eSchristos 	ret |= loongarch_encode_imm (bit_fields[i],
315*c42dbd0eSchristos 				     helper (esc1s[i], esc2s[i],
316*c42dbd0eSchristos 					     bit_fields[i], arg_strs[i],
317*c42dbd0eSchristos 					     context));
318*c42dbd0eSchristos       ret |= helper ('\0', '\0', NULL, NULL, context);
319*c42dbd0eSchristos     }
320*c42dbd0eSchristos 
321*c42dbd0eSchristos   return ret;
322*c42dbd0eSchristos }
323*c42dbd0eSchristos 
324*c42dbd0eSchristos int
loongarch_check_format(const char * format)325*c42dbd0eSchristos loongarch_check_format (const char *format)
326*c42dbd0eSchristos {
327*c42dbd0eSchristos   char esc1s[MAX_ARG_NUM_PLUS_2 - 1], esc2s[MAX_ARG_NUM_PLUS_2 - 1];
328*c42dbd0eSchristos   const char *bit_fields[MAX_ARG_NUM_PLUS_2 - 1];
329*c42dbd0eSchristos 
330*c42dbd0eSchristos   if (!format)
331*c42dbd0eSchristos     return -1;
332*c42dbd0eSchristos 
333*c42dbd0eSchristos   return loongarch_parse_format (format, esc1s, esc2s, bit_fields);
334*c42dbd0eSchristos }
335*c42dbd0eSchristos 
336*c42dbd0eSchristos int
loongarch_check_macro(const char * format,const char * macro)337*c42dbd0eSchristos loongarch_check_macro (const char *format, const char *macro)
338*c42dbd0eSchristos {
339*c42dbd0eSchristos   int num_of_args;
340*c42dbd0eSchristos   char esc1s[MAX_ARG_NUM_PLUS_2 - 1], esc2s[MAX_ARG_NUM_PLUS_2 - 1];
341*c42dbd0eSchristos   const char *bit_fields[MAX_ARG_NUM_PLUS_2 - 1];
342*c42dbd0eSchristos 
343*c42dbd0eSchristos   if (!format || !macro
344*c42dbd0eSchristos       || loongarch_parse_format (format, esc1s, esc2s, bit_fields) != 0)
345*c42dbd0eSchristos     return -1;
346*c42dbd0eSchristos 
347*c42dbd0eSchristos   for (num_of_args = 0; esc1s[num_of_args]; num_of_args++)
348*c42dbd0eSchristos     ;
349*c42dbd0eSchristos 
350*c42dbd0eSchristos   for (; macro[0]; macro++)
351*c42dbd0eSchristos     if (macro[0] == '%')
352*c42dbd0eSchristos       {
353*c42dbd0eSchristos 	macro++;
354*c42dbd0eSchristos 	if ('1' <= macro[0] && macro[0] <= '9')
355*c42dbd0eSchristos 	  {
356*c42dbd0eSchristos 	    if (num_of_args < macro[0] - '0')
357*c42dbd0eSchristos 	      /* Out of args num.  */
358*c42dbd0eSchristos 	      return -1;
359*c42dbd0eSchristos 	  }
360*c42dbd0eSchristos 	else if (macro[0] == 'f')
361*c42dbd0eSchristos 	  ;
362*c42dbd0eSchristos 	else if (macro[0] == '%')
363*c42dbd0eSchristos 	  ;
364*c42dbd0eSchristos 	else
365*c42dbd0eSchristos 	  return -1;
366*c42dbd0eSchristos       }
367*c42dbd0eSchristos   return 0;
368*c42dbd0eSchristos }
369*c42dbd0eSchristos 
370*c42dbd0eSchristos static const char *
I(char esc_ch1 ATTRIBUTE_UNUSED,char esc_ch2 ATTRIBUTE_UNUSED,const char * c_str)371*c42dbd0eSchristos I (char esc_ch1 ATTRIBUTE_UNUSED, char esc_ch2 ATTRIBUTE_UNUSED,
372*c42dbd0eSchristos    const char *c_str)
373*c42dbd0eSchristos {
374*c42dbd0eSchristos   return c_str;
375*c42dbd0eSchristos }
376*c42dbd0eSchristos 
377*c42dbd0eSchristos char *
loongarch_expand_macro_with_format_map(const char * format,const char * macro,const char * const arg_strs[],const char * (* map)(char esc1,char esc2,const char * arg),char * (* helper)(const char * const arg_strs[],void * context),void * context,size_t len_str)378*c42dbd0eSchristos loongarch_expand_macro_with_format_map (
379*c42dbd0eSchristos   const char *format, const char *macro, const char *const arg_strs[],
380*c42dbd0eSchristos   const char *(*map) (char esc1, char esc2, const char *arg),
381*c42dbd0eSchristos   char *(*helper) (const char *const arg_strs[], void *context), void *context,
382*c42dbd0eSchristos   size_t len_str)
383*c42dbd0eSchristos {
384*c42dbd0eSchristos   char esc1s[MAX_ARG_NUM_PLUS_2 - 1], esc2s[MAX_ARG_NUM_PLUS_2 - 1];
385*c42dbd0eSchristos   const char *bit_fields[MAX_ARG_NUM_PLUS_2 - 1];
386*c42dbd0eSchristos   const char *src;
387*c42dbd0eSchristos   char *dest;
388*c42dbd0eSchristos 
389*c42dbd0eSchristos   /* The expanded macro character length does not exceed 1000, and number of
390*c42dbd0eSchristos      label is 6 at most in the expanded macro. The len_str is the length of
391*c42dbd0eSchristos      str.  */
392*c42dbd0eSchristos   char *buffer =(char *) malloc(1024 +  6 * len_str);
393*c42dbd0eSchristos 
394*c42dbd0eSchristos   if (format)
395*c42dbd0eSchristos     loongarch_parse_format (format, esc1s, esc2s, bit_fields);
396*c42dbd0eSchristos 
397*c42dbd0eSchristos   src = macro;
398*c42dbd0eSchristos   dest = buffer;
399*c42dbd0eSchristos 
400*c42dbd0eSchristos   while (*src)
401*c42dbd0eSchristos     if (*src == '%')
402*c42dbd0eSchristos       {
403*c42dbd0eSchristos 	src++;
404*c42dbd0eSchristos 	if ('1' <= *src && *src <= '9')
405*c42dbd0eSchristos 	  {
406*c42dbd0eSchristos 	    size_t i = *src - '1';
407*c42dbd0eSchristos 	    const char *t = map (esc1s[i], esc2s[i], arg_strs[i]);
408*c42dbd0eSchristos 	    while (*t)
409*c42dbd0eSchristos 	      *dest++ = *t++;
410*c42dbd0eSchristos 	  }
411*c42dbd0eSchristos 	else if (*src == '%')
412*c42dbd0eSchristos 	  *dest++ = '%';
413*c42dbd0eSchristos 	else if (*src == 'f' && helper)
414*c42dbd0eSchristos 	  {
415*c42dbd0eSchristos 	    char *b, *t;
416*c42dbd0eSchristos 	    t = b = (*helper) (arg_strs, context);
417*c42dbd0eSchristos 	    if (b)
418*c42dbd0eSchristos 	      {
419*c42dbd0eSchristos 		while (*t)
420*c42dbd0eSchristos 		  *dest++ = *t++;
421*c42dbd0eSchristos 		free (b);
422*c42dbd0eSchristos 	      }
423*c42dbd0eSchristos 	  }
424*c42dbd0eSchristos 	src++;
425*c42dbd0eSchristos       }
426*c42dbd0eSchristos     else
427*c42dbd0eSchristos       *dest++ = *src++;
428*c42dbd0eSchristos 
429*c42dbd0eSchristos   *dest = '\0';
430*c42dbd0eSchristos   return buffer;
431*c42dbd0eSchristos }
432*c42dbd0eSchristos 
433*c42dbd0eSchristos char *
loongarch_expand_macro(const char * macro,const char * const arg_strs[],char * (* helper)(const char * const arg_strs[],void * context),void * context,size_t len_str)434*c42dbd0eSchristos loongarch_expand_macro (const char *macro, const char *const arg_strs[],
435*c42dbd0eSchristos 			char *(*helper) (const char *const arg_strs[],
436*c42dbd0eSchristos 					 void *context),
437*c42dbd0eSchristos 			void *context, size_t len_str)
438*c42dbd0eSchristos {
439*c42dbd0eSchristos   return loongarch_expand_macro_with_format_map (NULL, macro, arg_strs, I,
440*c42dbd0eSchristos 						 helper, context, len_str);
441*c42dbd0eSchristos }
442*c42dbd0eSchristos 
443*c42dbd0eSchristos size_t
loongarch_bits_imm_needed(int64_t imm,int si)444*c42dbd0eSchristos loongarch_bits_imm_needed (int64_t imm, int si)
445*c42dbd0eSchristos {
446*c42dbd0eSchristos   size_t ret;
447*c42dbd0eSchristos   if (si)
448*c42dbd0eSchristos     {
449*c42dbd0eSchristos       if (imm < 0)
450*c42dbd0eSchristos 	{
451*c42dbd0eSchristos 	  uint64_t uimm = (uint64_t) imm;
452*c42dbd0eSchristos 	  uint64_t uimax = UINT64_C (1) << 63;
453*c42dbd0eSchristos 	  for (ret = 0; (uimm & uimax) != 0; uimm <<= 1, ret++)
454*c42dbd0eSchristos 	    ;
455*c42dbd0eSchristos 	  ret = 64 - ret + 1;
456*c42dbd0eSchristos 	}
457*c42dbd0eSchristos       else
458*c42dbd0eSchristos 	ret = loongarch_bits_imm_needed (imm, 0) + 1;
459*c42dbd0eSchristos     }
460*c42dbd0eSchristos   else
461*c42dbd0eSchristos     {
462*c42dbd0eSchristos       uint64_t t = imm;
463*c42dbd0eSchristos       for (ret = 0; t; t >>= 1, ret++)
464*c42dbd0eSchristos 	;
465*c42dbd0eSchristos     }
466*c42dbd0eSchristos   return ret;
467*c42dbd0eSchristos }
468*c42dbd0eSchristos 
469*c42dbd0eSchristos void
loongarch_eliminate_adjacent_repeat_char(char * dest,char c)470*c42dbd0eSchristos loongarch_eliminate_adjacent_repeat_char (char *dest, char c)
471*c42dbd0eSchristos {
472*c42dbd0eSchristos   if (c == '\0')
473*c42dbd0eSchristos     return;
474*c42dbd0eSchristos   char *src = dest;
475*c42dbd0eSchristos   while (*dest)
476*c42dbd0eSchristos     {
477*c42dbd0eSchristos       while (src[0] == c && src[0] == src[1])
478*c42dbd0eSchristos 	src++;
479*c42dbd0eSchristos       *dest++ = *src++;
480*c42dbd0eSchristos     }
481*c42dbd0eSchristos }
482