]> Git Repo - binutils.git/blob - sim/mcore/interp.c
Automatic date update in version.in
[binutils.git] / sim / mcore / interp.c
1 /* Simulator for Motorola's MCore processor
2    Copyright (C) 1999-2022 Free Software Foundation, Inc.
3    Contributed by Cygnus Solutions.
4
5 This file is part of GDB, the GNU debugger.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20 /* This must come before any other includes.  */
21 #include "defs.h"
22
23 #include <signal.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <sys/param.h>
27 #include <unistd.h>
28 #include "bfd.h"
29 #include "sim/callback.h"
30 #include "libiberty.h"
31 #include "sim/sim.h"
32
33 #include "sim-main.h"
34 #include "sim-base.h"
35 #include "sim-signal.h"
36 #include "sim-syscall.h"
37 #include "sim-options.h"
38
39 #include "target-newlib-syscall.h"
40
41 #define target_big_endian (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN)
42
43
44 static unsigned long
45 mcore_extract_unsigned_integer (const unsigned char *addr, int len)
46 {
47   unsigned long retval;
48   unsigned char * p;
49   unsigned char * startaddr = (unsigned char *)addr;
50   unsigned char * endaddr = startaddr + len;
51
52   if (len > (int) sizeof (unsigned long))
53     printf ("That operation is not available on integers of more than %zu bytes.",
54             sizeof (unsigned long));
55
56   /* Start at the most significant end of the integer, and work towards
57      the least significant.  */
58   retval = 0;
59
60   if (! target_big_endian)
61     {
62       for (p = endaddr; p > startaddr;)
63         retval = (retval << 8) | * -- p;
64     }
65   else
66     {
67       for (p = startaddr; p < endaddr;)
68         retval = (retval << 8) | * p ++;
69     }
70
71   return retval;
72 }
73
74 static void
75 mcore_store_unsigned_integer (unsigned char *addr, int len, unsigned long val)
76 {
77   unsigned char * p;
78   unsigned char * startaddr = (unsigned char *)addr;
79   unsigned char * endaddr = startaddr + len;
80
81   if (! target_big_endian)
82     {
83       for (p = startaddr; p < endaddr;)
84         {
85           * p ++ = val & 0xff;
86           val >>= 8;
87         }
88     }
89   else
90     {
91       for (p = endaddr; p > startaddr;)
92         {
93           * -- p = val & 0xff;
94           val >>= 8;
95         }
96     }
97 }
98
99 static int memcycles = 1;
100
101 #define gr      cpu->active_gregs
102 #define cr      cpu->regs.cregs
103 #define sr      cr[0]
104 #define vbr     cr[1]
105 #define esr     cr[2]
106 #define fsr     cr[3]
107 #define epc     cr[4]
108 #define fpc     cr[5]
109 #define ss0     cr[6]
110 #define ss1     cr[7]
111 #define ss2     cr[8]
112 #define ss3     cr[9]
113 #define ss4     cr[10]
114 #define gcr     cr[11]
115 #define gsr     cr[12]
116
117 /* maniuplate the carry bit */
118 #define C_ON()          (sr & 1)
119 #define C_VALUE()       (sr & 1)
120 #define C_OFF()         ((sr & 1) == 0)
121 #define SET_C()         {sr |= 1;}
122 #define CLR_C()         {sr &= 0xfffffffe;}
123 #define NEW_C(v)        {CLR_C(); sr |= ((v) & 1);}
124
125 #define SR_AF()         ((sr >> 1) & 1)
126 static void set_active_regs (SIM_CPU *cpu)
127 {
128   if (SR_AF())
129     cpu->active_gregs = cpu->regs.alt_gregs;
130   else
131     cpu->active_gregs = cpu->regs.gregs;
132 }
133
134 #define TRAPCODE        1       /* r1 holds which function we want */
135 #define PARM1   2               /* first parameter  */
136 #define PARM2   3
137 #define PARM3   4
138 #define PARM4   5
139 #define RET1    2               /* register for return values. */
140
141 /* Default to a 8 Mbyte (== 2^23) memory space.  */
142 #define DEFAULT_MEMORY_SIZE 0x800000
143
144 static void
145 set_initial_gprs (SIM_CPU *cpu)
146 {
147   /* Set up machine just out of reset.  */
148   CPU_PC_SET (cpu, 0);
149   sr = 0;
150
151   /* Clean out the GPRs and alternate GPRs.  */
152   memset (&cpu->regs.gregs, 0, sizeof(cpu->regs.gregs));
153   memset (&cpu->regs.alt_gregs, 0, sizeof(cpu->regs.alt_gregs));
154
155   /* Make our register set point to the right place.  */
156   set_active_regs (cpu);
157
158   /* ABI specifies initial values for these registers.  */
159   gr[0] = DEFAULT_MEMORY_SIZE - 4;
160
161   /* dac fix, the stack address must be 8-byte aligned! */
162   gr[0] = gr[0] - gr[0] % 8;
163   gr[PARM1] = 0;
164   gr[PARM2] = 0;
165   gr[PARM3] = 0;
166   gr[PARM4] = gr[0];
167 }
168
169 /* Simulate a monitor trap.  */
170
171 static void
172 handle_trap1 (SIM_DESC sd, SIM_CPU *cpu)
173 {
174   /* XXX: We don't pass back the actual errno value.  */
175   gr[RET1] = sim_syscall (cpu, gr[TRAPCODE], gr[PARM1], gr[PARM2], gr[PARM3],
176                           gr[PARM4]);
177 }
178
179 static void
180 process_stub (SIM_DESC sd, SIM_CPU *cpu, int what)
181 {
182   /* These values should match those in libgloss/mcore/syscalls.s.  */
183   switch (what)
184     {
185     case 3:  /* _read */
186     case 4:  /* _write */
187     case 5:  /* _open */
188     case 6:  /* _close */
189     case 10: /* _unlink */
190     case 19: /* _lseek */
191     case 43: /* _times */
192       gr[TRAPCODE] = what;
193       handle_trap1 (sd, cpu);
194       break;
195
196     default:
197       if (STATE_VERBOSE_P (sd))
198         fprintf (stderr, "Unhandled stub opcode: %d\n", what);
199       break;
200     }
201 }
202
203 static void
204 util (SIM_DESC sd, SIM_CPU *cpu, unsigned what)
205 {
206   switch (what)
207     {
208     case 0:     /* exit */
209       sim_engine_halt (sd, cpu, NULL, cpu->regs.pc, sim_exited, gr[PARM1]);
210       break;
211
212     case 1:     /* printf */
213       if (STATE_VERBOSE_P (sd))
214         fprintf (stderr, "WARNING: printf unimplemented\n");
215       break;
216
217     case 2:     /* scanf */
218       if (STATE_VERBOSE_P (sd))
219         fprintf (stderr, "WARNING: scanf unimplemented\n");
220       break;
221
222     case 3:     /* utime */
223       gr[RET1] = cpu->insts;
224       break;
225
226     case 0xFF:
227       process_stub (sd, cpu, gr[1]);
228       break;
229
230     default:
231       if (STATE_VERBOSE_P (sd))
232         fprintf (stderr, "Unhandled util code: %x\n", what);
233       break;
234     }
235 }
236
237 /* For figuring out whether we carried; addc/subc use this. */
238 static int
239 iu_carry (unsigned long a, unsigned long b, int cin)
240 {
241   unsigned long x;
242
243   x = (a & 0xffff) + (b & 0xffff) + cin;
244   x = (x >> 16) + (a >> 16) + (b >> 16);
245   x >>= 16;
246
247   return (x != 0);
248 }
249
250 /* TODO: Convert to common watchpoints.  */
251 #undef WATCHFUNCTIONS
252 #ifdef WATCHFUNCTIONS
253
254 #define MAXWL 80
255 word WL[MAXWL];
256 char * WLstr[MAXWL];
257
258 int ENDWL=0;
259 int WLincyc;
260 int WLcyc[MAXWL];
261 int WLcnts[MAXWL];
262 int WLmax[MAXWL];
263 int WLmin[MAXWL];
264 word WLendpc;
265 int WLbcyc;
266 int WLW;
267 #endif
268
269 #define RD      (inst        & 0xF)
270 #define RS      ((inst >> 4) & 0xF)
271 #define RX      ((inst >> 8) & 0xF)
272 #define IMM5    ((inst >> 4) & 0x1F)
273 #define IMM4    ((inst) & 0xF)
274
275 #define rbat(X) sim_core_read_1 (cpu, 0, read_map, X)
276 #define rhat(X) sim_core_read_2 (cpu, 0, read_map, X)
277 #define rlat(X) sim_core_read_4 (cpu, 0, read_map, X)
278 #define wbat(X, D) sim_core_write_1 (cpu, 0, write_map, X, D)
279 #define what(X, D) sim_core_write_2 (cpu, 0, write_map, X, D)
280 #define wlat(X, D) sim_core_write_4 (cpu, 0, write_map, X, D)
281
282 static int tracing = 0;
283
284 #define ILLEGAL() \
285   sim_engine_halt (sd, cpu, NULL, pc, sim_stopped, SIM_SIGILL)
286
287 static void
288 step_once (SIM_DESC sd, SIM_CPU *cpu)
289 {
290   int needfetch;
291   word ibuf;
292   word pc;
293   unsigned short inst;
294   int memops;
295   int bonus_cycles;
296   int insts;
297   int w;
298   int cycs;
299 #ifdef WATCHFUNCTIONS
300   word WLhash;
301 #endif
302
303   pc = CPU_PC_GET (cpu);
304
305   /* Fetch the initial instructions that we'll decode. */
306   ibuf = rlat (pc & 0xFFFFFFFC);
307   needfetch = 0;
308
309   memops = 0;
310   bonus_cycles = 0;
311   insts = 0;
312
313   /* make our register set point to the right place */
314   set_active_regs (cpu);
315
316 #ifdef WATCHFUNCTIONS
317   /* make a hash to speed exec loop, hope it's nonzero */
318   WLhash = 0xFFFFFFFF;
319
320   for (w = 1; w <= ENDWL; w++)
321     WLhash = WLhash & WL[w];
322 #endif
323
324   /* TODO: Unindent this block.  */
325     {
326       word oldpc;
327
328       insts ++;
329
330       if (pc & 02)
331         {
332           if (! target_big_endian)
333             inst = ibuf >> 16;
334           else
335             inst = ibuf & 0xFFFF;
336           needfetch = 1;
337         }
338       else
339         {
340           if (! target_big_endian)
341             inst = ibuf & 0xFFFF;
342           else
343             inst = ibuf >> 16;
344         }
345
346 #ifdef WATCHFUNCTIONS
347       /* now scan list of watch addresses, if match, count it and
348          note return address and count cycles until pc=return address */
349
350       if ((WLincyc == 1) && (pc == WLendpc))
351         {
352           cycs = (cpu->cycles + (insts + bonus_cycles +
353                                        (memops * memcycles)) - WLbcyc);
354
355           if (WLcnts[WLW] == 1)
356             {
357               WLmax[WLW] = cycs;
358               WLmin[WLW] = cycs;
359               WLcyc[WLW] = 0;
360             }
361
362           if (cycs > WLmax[WLW])
363             {
364               WLmax[WLW] = cycs;
365             }
366
367           if (cycs < WLmin[WLW])
368             {
369               WLmin[WLW] = cycs;
370             }
371
372           WLcyc[WLW] += cycs;
373           WLincyc = 0;
374           WLendpc = 0;
375         }
376
377       /* Optimize with a hash to speed loop.  */
378       if (WLincyc == 0)
379         {
380           if ((WLhash == 0) || ((WLhash & pc) != 0))
381             {
382               for (w=1; w <= ENDWL; w++)
383                 {
384                   if (pc == WL[w])
385                     {
386                       WLcnts[w]++;
387                       WLbcyc = cpu->cycles + insts
388                         + bonus_cycles + (memops * memcycles);
389                       WLendpc = gr[15];
390                       WLincyc = 1;
391                       WLW = w;
392                       break;
393                     }
394                 }
395             }
396         }
397 #endif
398
399       if (tracing)
400         fprintf (stderr, "%.4lx: inst = %.4x ", pc, inst);
401
402       oldpc = pc;
403
404       pc += 2;
405
406       switch (inst >> 8)
407         {
408         case 0x00:
409           switch RS
410             {
411             case 0x0:
412               switch RD
413                 {
414                 case 0x0:                               /* bkpt */
415                   pc -= 2;
416                   sim_engine_halt (sd, cpu, NULL, pc - 2,
417                                    sim_stopped, SIM_SIGTRAP);
418                   break;
419
420                 case 0x1:                               /* sync */
421                   break;
422
423                 case 0x2:                               /* rte */
424                   pc = epc;
425                   sr = esr;
426                   needfetch = 1;
427
428                   set_active_regs (cpu);
429                   break;
430
431                 case 0x3:                               /* rfi */
432                   pc = fpc;
433                   sr = fsr;
434                   needfetch = 1;
435
436                   set_active_regs (cpu);
437                   break;
438
439                 case 0x4:                               /* stop */
440                   if (STATE_VERBOSE_P (sd))
441                     fprintf (stderr, "WARNING: stop unimplemented\n");
442                   break;
443
444                 case 0x5:                               /* wait */
445                   if (STATE_VERBOSE_P (sd))
446                     fprintf (stderr, "WARNING: wait unimplemented\n");
447                   break;
448
449                 case 0x6:                               /* doze */
450                   if (STATE_VERBOSE_P (sd))
451                     fprintf (stderr, "WARNING: doze unimplemented\n");
452                   break;
453
454                 case 0x7:
455                   ILLEGAL ();                           /* illegal */
456                   break;
457
458                 case 0x8:                               /* trap 0 */
459                 case 0xA:                               /* trap 2 */
460                 case 0xB:                               /* trap 3 */
461                   sim_engine_halt (sd, cpu, NULL, pc,
462                                    sim_stopped, SIM_SIGTRAP);
463                   break;
464
465                 case 0xC:                               /* trap 4 */
466                 case 0xD:                               /* trap 5 */
467                 case 0xE:                               /* trap 6 */
468                   ILLEGAL ();                           /* illegal */
469                   break;
470
471                 case 0xF:                               /* trap 7 */
472                   sim_engine_halt (sd, cpu, NULL, pc,   /* integer div-by-0 */
473                                    sim_stopped, SIM_SIGTRAP);
474                   break;
475
476                 case 0x9:                               /* trap 1 */
477                   handle_trap1 (sd, cpu);
478                   break;
479                 }
480               break;
481
482             case 0x1:
483               ILLEGAL ();                               /* illegal */
484               break;
485
486             case 0x2:                                   /* mvc */
487               gr[RD] = C_VALUE();
488               break;
489             case 0x3:                                   /* mvcv */
490               gr[RD] = C_OFF();
491               break;
492             case 0x4:                                   /* ldq */
493               {
494                 word addr = gr[RD];
495                 int regno = 4;                  /* always r4-r7 */
496
497                 bonus_cycles++;
498                 memops += 4;
499                 do
500                   {
501                     gr[regno] = rlat (addr);
502                     addr += 4;
503                     regno++;
504                   }
505                 while ((regno&0x3) != 0);
506               }
507               break;
508             case 0x5:                                   /* stq */
509               {
510                 word addr = gr[RD];
511                 int regno = 4;                  /* always r4-r7 */
512
513                 memops += 4;
514                 bonus_cycles++;
515                 do
516                   {
517                     wlat (addr, gr[regno]);
518                     addr += 4;
519                     regno++;
520                   }
521                 while ((regno & 0x3) != 0);
522               }
523               break;
524             case 0x6:                                   /* ldm */
525               {
526                 word addr = gr[0];
527                 int regno = RD;
528
529                 /* bonus cycle is really only needed if
530                    the next insn shifts the last reg loaded.
531
532                    bonus_cycles++;
533                 */
534                 memops += 16-regno;
535                 while (regno <= 0xF)
536                   {
537                     gr[regno] = rlat (addr);
538                     addr += 4;
539                     regno++;
540                   }
541               }
542               break;
543             case 0x7:                                   /* stm */
544               {
545                 word addr = gr[0];
546                 int regno = RD;
547
548                 /* this should be removed! */
549                 /*  bonus_cycles ++; */
550
551                 memops += 16 - regno;
552                 while (regno <= 0xF)
553                   {
554                     wlat (addr, gr[regno]);
555                     addr += 4;
556                     regno++;
557                   }
558               }
559               break;
560
561             case 0x8:                                   /* dect */
562               gr[RD] -= C_VALUE();
563               break;
564             case 0x9:                                   /* decf */
565               gr[RD] -= C_OFF();
566               break;
567             case 0xA:                                   /* inct */
568               gr[RD] += C_VALUE();
569               break;
570             case 0xB:                                   /* incf */
571               gr[RD] += C_OFF();
572               break;
573             case 0xC:                                   /* jmp */
574               pc = gr[RD];
575               if (tracing && RD == 15)
576                 fprintf (stderr, "Func return, r2 = %lxx, r3 = %lx\n",
577                          gr[2], gr[3]);
578               bonus_cycles++;
579               needfetch = 1;
580               break;
581             case 0xD:                                   /* jsr */
582               gr[15] = pc;
583               pc = gr[RD];
584               bonus_cycles++;
585               needfetch = 1;
586               break;
587             case 0xE:                                   /* ff1 */
588               {
589                 word tmp, i;
590                 tmp = gr[RD];
591                 for (i = 0; !(tmp & 0x80000000) && i < 32; i++)
592                   tmp <<= 1;
593                 gr[RD] = i;
594               }
595               break;
596             case 0xF:                                   /* brev */
597               {
598                 word tmp;
599                 tmp = gr[RD];
600                 tmp = ((tmp & 0xaaaaaaaa) >>  1) | ((tmp & 0x55555555) <<  1);
601                 tmp = ((tmp & 0xcccccccc) >>  2) | ((tmp & 0x33333333) <<  2);
602                 tmp = ((tmp & 0xf0f0f0f0) >>  4) | ((tmp & 0x0f0f0f0f) <<  4);
603                 tmp = ((tmp & 0xff00ff00) >>  8) | ((tmp & 0x00ff00ff) <<  8);
604                 gr[RD] = ((tmp & 0xffff0000) >> 16) | ((tmp & 0x0000ffff) << 16);
605               }
606               break;
607             }
608           break;
609         case 0x01:
610           switch RS
611             {
612             case 0x0:                                   /* xtrb3 */
613               gr[1] = (gr[RD]) & 0xFF;
614               NEW_C (gr[RD] != 0);
615               break;
616             case 0x1:                                   /* xtrb2 */
617               gr[1] = (gr[RD]>>8) & 0xFF;
618               NEW_C (gr[RD] != 0);
619               break;
620             case 0x2:                                   /* xtrb1 */
621               gr[1] = (gr[RD]>>16) & 0xFF;
622               NEW_C (gr[RD] != 0);
623               break;
624             case 0x3:                                   /* xtrb0 */
625               gr[1] = (gr[RD]>>24) & 0xFF;
626               NEW_C (gr[RD] != 0);
627               break;
628             case 0x4:                                   /* zextb */
629               gr[RD] &= 0x000000FF;
630               break;
631             case 0x5:                                   /* sextb */
632               {
633                 long tmp;
634                 tmp = gr[RD];
635                 tmp <<= 24;
636                 tmp >>= 24;
637                 gr[RD] = tmp;
638               }
639               break;
640             case 0x6:                                   /* zexth */
641               gr[RD] &= 0x0000FFFF;
642               break;
643             case 0x7:                                   /* sexth */
644               {
645                 long tmp;
646                 tmp = gr[RD];
647                 tmp <<= 16;
648                 tmp >>= 16;
649                 gr[RD] = tmp;
650               }
651               break;
652             case 0x8:                                   /* declt */
653               --gr[RD];
654               NEW_C ((long)gr[RD] < 0);
655               break;
656             case 0x9:                                   /* tstnbz */
657               {
658                 word tmp = gr[RD];
659                 NEW_C ((tmp & 0xFF000000) != 0 &&
660                        (tmp & 0x00FF0000) != 0 && (tmp & 0x0000FF00) != 0 &&
661                        (tmp & 0x000000FF) != 0);
662               }
663               break;
664             case 0xA:                                   /* decgt */
665               --gr[RD];
666               NEW_C ((long)gr[RD] > 0);
667               break;
668             case 0xB:                                   /* decne */
669               --gr[RD];
670               NEW_C ((long)gr[RD] != 0);
671               break;
672             case 0xC:                                   /* clrt */
673               if (C_ON())
674                 gr[RD] = 0;
675               break;
676             case 0xD:                                   /* clrf */
677               if (C_OFF())
678                 gr[RD] = 0;
679               break;
680             case 0xE:                                   /* abs */
681               if (gr[RD] & 0x80000000)
682                 gr[RD] = ~gr[RD] + 1;
683               break;
684             case 0xF:                                   /* not */
685               gr[RD] = ~gr[RD];
686               break;
687             }
688           break;
689         case 0x02:                                      /* movt */
690           if (C_ON())
691             gr[RD] = gr[RS];
692           break;
693         case 0x03:                                      /* mult */
694           /* consume 2 bits per cycle from rs, until rs is 0 */
695           {
696             unsigned int t = gr[RS];
697             int ticks;
698             for (ticks = 0; t != 0 ; t >>= 2)
699               ticks++;
700             bonus_cycles += ticks;
701           }
702           bonus_cycles += 2;  /* min. is 3, so add 2, plus ticks above */
703           if (tracing)
704             fprintf (stderr, "  mult %lx by %lx to give %lx",
705                      gr[RD], gr[RS], gr[RD] * gr[RS]);
706           gr[RD] = gr[RD] * gr[RS];
707           break;
708         case 0x04:                                      /* loopt */
709           if (C_ON())
710             {
711               pc += (IMM4 << 1) - 32;
712               bonus_cycles ++;
713               needfetch = 1;
714             }
715           --gr[RS];                             /* not RD! */
716           NEW_C (((long)gr[RS]) > 0);
717           break;
718         case 0x05:                                      /* subu */
719           gr[RD] -= gr[RS];
720           break;
721         case 0x06:                                      /* addc */
722           {
723             unsigned long tmp, a, b;
724             a = gr[RD];
725             b = gr[RS];
726             gr[RD] = a + b + C_VALUE ();
727             tmp = iu_carry (a, b, C_VALUE ());
728             NEW_C (tmp);
729           }
730           break;
731         case 0x07:                                      /* subc */
732           {
733             unsigned long tmp, a, b;
734             a = gr[RD];
735             b = gr[RS];
736             gr[RD] = a - b + C_VALUE () - 1;
737             tmp = iu_carry (a,~b, C_VALUE ());
738             NEW_C (tmp);
739           }
740           break;
741         case 0x08:                                      /* illegal */
742         case 0x09:                                      /* illegal*/
743           ILLEGAL ();
744           break;
745         case 0x0A:                                      /* movf */
746           if (C_OFF())
747             gr[RD] = gr[RS];
748           break;
749         case 0x0B:                                      /* lsr */
750           {
751             unsigned long dst, src;
752             dst = gr[RD];
753             src = gr[RS];
754             /* We must not rely solely upon the native shift operations, since they
755                may not match the M*Core's behaviour on boundary conditions.  */
756             dst = src > 31 ? 0 : dst >> src;
757             gr[RD] = dst;
758           }
759           break;
760         case 0x0C:                                      /* cmphs */
761           NEW_C ((unsigned long )gr[RD] >=
762                  (unsigned long)gr[RS]);
763           break;
764         case 0x0D:                                      /* cmplt */
765           NEW_C ((long)gr[RD] < (long)gr[RS]);
766           break;
767         case 0x0E:                                      /* tst */
768           NEW_C ((gr[RD] & gr[RS]) != 0);
769           break;
770         case 0x0F:                                      /* cmpne */
771           NEW_C (gr[RD] != gr[RS]);
772           break;
773         case 0x10: case 0x11:                           /* mfcr */
774           {
775             unsigned r;
776             r = IMM5;
777             if (r <= LAST_VALID_CREG)
778               gr[RD] = cr[r];
779             else
780               ILLEGAL ();
781           }
782           break;
783
784         case 0x12:                                      /* mov */
785           gr[RD] = gr[RS];
786           if (tracing)
787             fprintf (stderr, "MOV %lx into reg %d", gr[RD], RD);
788           break;
789
790         case 0x13:                                      /* bgenr */
791           if (gr[RS] & 0x20)
792             gr[RD] = 0;
793           else
794             gr[RD] = 1 << (gr[RS] & 0x1F);
795           break;
796
797         case 0x14:                                      /* rsub */
798           gr[RD] = gr[RS] - gr[RD];
799           break;
800
801         case 0x15:                                      /* ixw */
802           gr[RD] += gr[RS]<<2;
803           break;
804
805         case 0x16:                                      /* and */
806           gr[RD] &= gr[RS];
807           break;
808
809         case 0x17:                                      /* xor */
810           gr[RD] ^= gr[RS];
811           break;
812
813         case 0x18: case 0x19:                           /* mtcr */
814           {
815             unsigned r;
816             r = IMM5;
817             if (r <= LAST_VALID_CREG)
818               cr[r] = gr[RD];
819             else
820               ILLEGAL ();
821
822             /* we might have changed register sets... */
823             set_active_regs (cpu);
824           }
825           break;
826
827         case 0x1A:                                      /* asr */
828           /* We must not rely solely upon the native shift operations, since they
829              may not match the M*Core's behaviour on boundary conditions.  */
830           if (gr[RS] > 30)
831             gr[RD] = ((long) gr[RD]) < 0 ? -1 : 0;
832           else
833             gr[RD] = (long) gr[RD] >> gr[RS];
834           break;
835
836         case 0x1B:                                      /* lsl */
837           /* We must not rely solely upon the native shift operations, since they
838              may not match the M*Core's behaviour on boundary conditions.  */
839           gr[RD] = gr[RS] > 31 ? 0 : gr[RD] << gr[RS];
840           break;
841
842         case 0x1C:                                      /* addu */
843           gr[RD] += gr[RS];
844           break;
845
846         case 0x1D:                                      /* ixh */
847           gr[RD] += gr[RS] << 1;
848           break;
849
850         case 0x1E:                                      /* or */
851           gr[RD] |= gr[RS];
852           break;
853
854         case 0x1F:                                      /* andn */
855           gr[RD] &= ~gr[RS];
856           break;
857         case 0x20: case 0x21:                           /* addi */
858           gr[RD] =
859             gr[RD] + (IMM5 + 1);
860           break;
861         case 0x22: case 0x23:                           /* cmplti */
862           {
863             int tmp = (IMM5 + 1);
864             if (gr[RD] < tmp)
865               {
866                 SET_C();
867               }
868             else
869               {
870                 CLR_C();
871               }
872           }
873           break;
874         case 0x24: case 0x25:                           /* subi */
875           gr[RD] =
876             gr[RD] - (IMM5 + 1);
877           break;
878         case 0x26: case 0x27:                           /* illegal */
879           ILLEGAL ();
880           break;
881         case 0x28: case 0x29:                           /* rsubi */
882           gr[RD] =
883             IMM5 - gr[RD];
884           break;
885         case 0x2A: case 0x2B:                           /* cmpnei */
886           if (gr[RD] != IMM5)
887             {
888               SET_C();
889             }
890           else
891             {
892               CLR_C();
893             }
894           break;
895
896         case 0x2C: case 0x2D:                           /* bmaski, divu */
897           {
898             unsigned imm = IMM5;
899
900             if (imm == 1)
901               {
902                 int exe;
903                 int rxnlz, r1nlz;
904                 unsigned int rx, r1;
905
906                 rx = gr[RD];
907                 r1 = gr[1];
908                 exe = 0;
909
910                 /* unsigned divide */
911                 gr[RD] = (word) ((unsigned int) gr[RD] / (unsigned int)gr[1] );
912
913                 /* compute bonus_cycles for divu */
914                 for (r1nlz = 0; ((r1 & 0x80000000) == 0) && (r1nlz < 32); r1nlz ++)
915                   r1 = r1 << 1;
916
917                 for (rxnlz = 0; ((rx & 0x80000000) == 0) && (rxnlz < 32); rxnlz ++)
918                   rx = rx << 1;
919
920                 if (r1nlz < rxnlz)
921                   exe += 4;
922                 else
923                   exe += 5 + r1nlz - rxnlz;
924
925                 if (exe >= (2 * memcycles - 1))
926                   {
927                     bonus_cycles += exe - (2 * memcycles) + 1;
928                   }
929               }
930             else if (imm == 0 || imm >= 8)
931               {
932                 /* bmaski */
933                 if (imm == 0)
934                   gr[RD] = -1;
935                 else
936                   gr[RD] = (1 << imm) - 1;
937               }
938             else
939               {
940                 /* illegal */
941                 ILLEGAL ();
942               }
943           }
944           break;
945         case 0x2E: case 0x2F:                           /* andi */
946           gr[RD] = gr[RD] & IMM5;
947           break;
948         case 0x30: case 0x31:                           /* bclri */
949           gr[RD] = gr[RD] & ~(1<<IMM5);
950           break;
951         case 0x32: case 0x33:                           /* bgeni, divs */
952           {
953             unsigned imm = IMM5;
954             if (imm == 1)
955               {
956                 int exe,sc;
957                 int rxnlz, r1nlz;
958                 signed int rx, r1;
959
960                 /* compute bonus_cycles for divu */
961                 rx = gr[RD];
962                 r1 = gr[1];
963                 exe = 0;
964
965                 if (((rx < 0) && (r1 > 0)) || ((rx >= 0) && (r1 < 0)))
966                   sc = 1;
967                 else
968                   sc = 0;
969
970                 rx = abs (rx);
971                 r1 = abs (r1);
972
973                 /* signed divide, general registers are of type int, so / op is OK */
974                 gr[RD] = gr[RD] / gr[1];
975
976                 for (r1nlz = 0; ((r1 & 0x80000000) == 0) && (r1nlz < 32) ; r1nlz ++ )
977                   r1 = r1 << 1;
978
979                 for (rxnlz = 0; ((rx & 0x80000000) == 0) && (rxnlz < 32) ; rxnlz ++ )
980                   rx = rx << 1;
981
982                 if (r1nlz < rxnlz)
983                   exe += 5;
984                 else
985                   exe += 6 + r1nlz - rxnlz + sc;
986
987                 if (exe >= (2 * memcycles - 1))
988                   {
989                     bonus_cycles += exe - (2 * memcycles) + 1;
990                   }
991               }
992             else if (imm >= 7)
993               {
994                 /* bgeni */
995                 gr[RD] = (1 << IMM5);
996               }
997             else
998               {
999                 /* illegal */
1000                 ILLEGAL ();
1001               }
1002             break;
1003           }
1004         case 0x34: case 0x35:                           /* bseti */
1005           gr[RD] = gr[RD] | (1 << IMM5);
1006           break;
1007         case 0x36: case 0x37:                           /* btsti */
1008           NEW_C (gr[RD] >> IMM5);
1009           break;
1010         case 0x38: case 0x39:                           /* xsr, rotli */
1011           {
1012             unsigned imm = IMM5;
1013             unsigned long tmp = gr[RD];
1014             if (imm == 0)
1015               {
1016                 word cbit;
1017                 cbit = C_VALUE();
1018                 NEW_C (tmp);
1019                 gr[RD] = (cbit << 31) | (tmp >> 1);
1020               }
1021             else
1022               gr[RD] = (tmp << imm) | (tmp >> (32 - imm));
1023           }
1024           break;
1025         case 0x3A: case 0x3B:                           /* asrc, asri */
1026           {
1027             unsigned imm = IMM5;
1028             long tmp = gr[RD];
1029             if (imm == 0)
1030               {
1031                 NEW_C (tmp);
1032                 gr[RD] = tmp >> 1;
1033               }
1034             else
1035               gr[RD] = tmp >> imm;
1036           }
1037           break;
1038         case 0x3C: case 0x3D:                           /* lslc, lsli */
1039           {
1040             unsigned imm = IMM5;
1041             unsigned long tmp = gr[RD];
1042             if (imm == 0)
1043               {
1044                 NEW_C (tmp >> 31);
1045                 gr[RD] = tmp << 1;
1046               }
1047             else
1048               gr[RD] = tmp << imm;
1049           }
1050           break;
1051         case 0x3E: case 0x3F:                           /* lsrc, lsri */
1052           {
1053             unsigned imm = IMM5;
1054             unsigned long tmp = gr[RD];
1055             if (imm == 0)
1056               {
1057                 NEW_C (tmp);
1058                 gr[RD] = tmp >> 1;
1059               }
1060             else
1061               gr[RD] = tmp >> imm;
1062           }
1063           break;
1064         case 0x40: case 0x41: case 0x42: case 0x43:
1065         case 0x44: case 0x45: case 0x46: case 0x47:
1066         case 0x48: case 0x49: case 0x4A: case 0x4B:
1067         case 0x4C: case 0x4D: case 0x4E: case 0x4F:
1068           ILLEGAL ();
1069           break;
1070         case 0x50:
1071           util (sd, cpu, inst & 0xFF);
1072           break;
1073         case 0x51: case 0x52: case 0x53:
1074         case 0x54: case 0x55: case 0x56: case 0x57:
1075         case 0x58: case 0x59: case 0x5A: case 0x5B:
1076         case 0x5C: case 0x5D: case 0x5E: case 0x5F:
1077           ILLEGAL ();
1078           break;
1079         case 0x60: case 0x61: case 0x62: case 0x63:     /* movi  */
1080         case 0x64: case 0x65: case 0x66: case 0x67:
1081           gr[RD] = (inst >> 4) & 0x7F;
1082           break;
1083         case 0x68: case 0x69: case 0x6A: case 0x6B:
1084         case 0x6C: case 0x6D: case 0x6E: case 0x6F:     /* illegal */
1085           ILLEGAL ();
1086           break;
1087         case 0x71: case 0x72: case 0x73:
1088         case 0x74: case 0x75: case 0x76: case 0x77:
1089         case 0x78: case 0x79: case 0x7A: case 0x7B:
1090         case 0x7C: case 0x7D: case 0x7E:                /* lrw */
1091           gr[RX] =  rlat ((pc + ((inst & 0xFF) << 2)) & 0xFFFFFFFC);
1092           if (tracing)
1093             fprintf (stderr, "LRW of 0x%x from 0x%lx to reg %d",
1094                      rlat ((pc + ((inst & 0xFF) << 2)) & 0xFFFFFFFC),
1095                      (pc + ((inst & 0xFF) << 2)) & 0xFFFFFFFC, RX);
1096           memops++;
1097           break;
1098         case 0x7F:                                      /* jsri */
1099           gr[15] = pc;
1100           if (tracing)
1101             fprintf (stderr,
1102                      "func call: r2 = %lx r3 = %lx r4 = %lx r5 = %lx r6 = %lx r7 = %lx\n",
1103                      gr[2], gr[3], gr[4], gr[5], gr[6], gr[7]);
1104         case 0x70:                                      /* jmpi */
1105           pc = rlat ((pc + ((inst & 0xFF) << 2)) & 0xFFFFFFFC);
1106           memops++;
1107           bonus_cycles++;
1108           needfetch = 1;
1109           break;
1110
1111         case 0x80: case 0x81: case 0x82: case 0x83:
1112         case 0x84: case 0x85: case 0x86: case 0x87:
1113         case 0x88: case 0x89: case 0x8A: case 0x8B:
1114         case 0x8C: case 0x8D: case 0x8E: case 0x8F:     /* ld */
1115           gr[RX] = rlat (gr[RD] + ((inst >> 2) & 0x003C));
1116           if (tracing)
1117             fprintf (stderr, "load reg %d from 0x%lx with 0x%lx",
1118                      RX,
1119                      gr[RD] + ((inst >> 2) & 0x003C), gr[RX]);
1120           memops++;
1121           break;
1122         case 0x90: case 0x91: case 0x92: case 0x93:
1123         case 0x94: case 0x95: case 0x96: case 0x97:
1124         case 0x98: case 0x99: case 0x9A: case 0x9B:
1125         case 0x9C: case 0x9D: case 0x9E: case 0x9F:     /* st */
1126           wlat (gr[RD] + ((inst >> 2) & 0x003C), gr[RX]);
1127           if (tracing)
1128             fprintf (stderr, "store reg %d (containing 0x%lx) to 0x%lx",
1129                      RX, gr[RX],
1130                      gr[RD] + ((inst >> 2) & 0x003C));
1131           memops++;
1132           break;
1133         case 0xA0: case 0xA1: case 0xA2: case 0xA3:
1134         case 0xA4: case 0xA5: case 0xA6: case 0xA7:
1135         case 0xA8: case 0xA9: case 0xAA: case 0xAB:
1136         case 0xAC: case 0xAD: case 0xAE: case 0xAF:     /* ld.b */
1137           gr[RX] = rbat (gr[RD] + RS);
1138           memops++;
1139           break;
1140         case 0xB0: case 0xB1: case 0xB2: case 0xB3:
1141         case 0xB4: case 0xB5: case 0xB6: case 0xB7:
1142         case 0xB8: case 0xB9: case 0xBA: case 0xBB:
1143         case 0xBC: case 0xBD: case 0xBE: case 0xBF:     /* st.b */
1144           wbat (gr[RD] + RS, gr[RX]);
1145           memops++;
1146           break;
1147         case 0xC0: case 0xC1: case 0xC2: case 0xC3:
1148         case 0xC4: case 0xC5: case 0xC6: case 0xC7:
1149         case 0xC8: case 0xC9: case 0xCA: case 0xCB:
1150         case 0xCC: case 0xCD: case 0xCE: case 0xCF:     /* ld.h */
1151           gr[RX] = rhat (gr[RD] + ((inst >> 3) & 0x001E));
1152           memops++;
1153           break;
1154         case 0xD0: case 0xD1: case 0xD2: case 0xD3:
1155         case 0xD4: case 0xD5: case 0xD6: case 0xD7:
1156         case 0xD8: case 0xD9: case 0xDA: case 0xDB:
1157         case 0xDC: case 0xDD: case 0xDE: case 0xDF:     /* st.h */
1158           what (gr[RD] + ((inst >> 3) & 0x001E), gr[RX]);
1159           memops++;
1160           break;
1161         case 0xE8: case 0xE9: case 0xEA: case 0xEB:
1162         case 0xEC: case 0xED: case 0xEE: case 0xEF:     /* bf */
1163           if (C_OFF())
1164             {
1165               int disp;
1166               disp = inst & 0x03FF;
1167               if (inst & 0x0400)
1168                 disp |= 0xFFFFFC00;
1169               pc += disp<<1;
1170               bonus_cycles++;
1171               needfetch = 1;
1172             }
1173           break;
1174         case 0xE0: case 0xE1: case 0xE2: case 0xE3:
1175         case 0xE4: case 0xE5: case 0xE6: case 0xE7:     /* bt */
1176           if (C_ON())
1177             {
1178               int disp;
1179               disp = inst & 0x03FF;
1180               if (inst & 0x0400)
1181                 disp |= 0xFFFFFC00;
1182               pc += disp<<1;
1183               bonus_cycles++;
1184               needfetch = 1;
1185             }
1186           break;
1187
1188         case 0xF8: case 0xF9: case 0xFA: case 0xFB:
1189         case 0xFC: case 0xFD: case 0xFE: case 0xFF:     /* bsr */
1190           gr[15] = pc;
1191         case 0xF0: case 0xF1: case 0xF2: case 0xF3:
1192         case 0xF4: case 0xF5: case 0xF6: case 0xF7:     /* br */
1193           {
1194             int disp;
1195             disp = inst & 0x03FF;
1196             if (inst & 0x0400)
1197               disp |= 0xFFFFFC00;
1198             pc += disp<<1;
1199             bonus_cycles++;
1200             needfetch = 1;
1201           }
1202           break;
1203
1204         }
1205
1206       if (tracing)
1207         fprintf (stderr, "\n");
1208
1209       if (needfetch)
1210         {
1211           ibuf = rlat (pc & 0xFFFFFFFC);
1212           needfetch = 0;
1213         }
1214     }
1215
1216   /* Hide away the things we've cached while executing.  */
1217   CPU_PC_SET (cpu, pc);
1218   cpu->insts += insts;          /* instructions done ... */
1219   cpu->cycles += insts;         /* and each takes a cycle */
1220   cpu->cycles += bonus_cycles;  /* and extra cycles for branches */
1221   cpu->cycles += memops * memcycles;    /* and memop cycle delays */
1222 }
1223
1224 void
1225 sim_engine_run (SIM_DESC sd,
1226                 int next_cpu_nr,  /* ignore  */
1227                 int nr_cpus,      /* ignore  */
1228                 int siggnal)      /* ignore  */
1229 {
1230   sim_cpu *cpu;
1231
1232   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
1233
1234   cpu = STATE_CPU (sd, 0);
1235
1236   while (1)
1237     {
1238       step_once (sd, cpu);
1239       if (sim_events_tick (sd))
1240         sim_events_process (sd);
1241     }
1242 }
1243
1244 static int
1245 mcore_reg_store (SIM_CPU *cpu, int rn, const void *memory, int length)
1246 {
1247   if (rn < NUM_MCORE_REGS && rn >= 0)
1248     {
1249       if (length == 4)
1250         {
1251           long ival;
1252
1253           /* misalignment safe */
1254           ival = mcore_extract_unsigned_integer (memory, 4);
1255           cpu->asints[rn] = ival;
1256         }
1257
1258       return 4;
1259     }
1260   else
1261     return 0;
1262 }
1263
1264 static int
1265 mcore_reg_fetch (SIM_CPU *cpu, int rn, void *memory, int length)
1266 {
1267   if (rn < NUM_MCORE_REGS && rn >= 0)
1268     {
1269       if (length == 4)
1270         {
1271           long ival = cpu->asints[rn];
1272
1273           /* misalignment-safe */
1274           mcore_store_unsigned_integer (memory, 4, ival);
1275         }
1276
1277       return 4;
1278     }
1279   else
1280     return 0;
1281 }
1282
1283 void
1284 sim_info (SIM_DESC sd, int verbose)
1285 {
1286   SIM_CPU *cpu = STATE_CPU (sd, 0);
1287 #ifdef WATCHFUNCTIONS
1288   int w, wcyc;
1289 #endif
1290   double virttime = cpu->cycles / 36.0e6;
1291   host_callback *callback = STATE_CALLBACK (sd);
1292
1293   callback->printf_filtered (callback, "\n\n# instructions executed  %10d\n",
1294                              cpu->insts);
1295   callback->printf_filtered (callback, "# cycles                 %10d\n",
1296                              cpu->cycles);
1297   callback->printf_filtered (callback, "# pipeline stalls        %10d\n",
1298                              cpu->stalls);
1299   callback->printf_filtered (callback, "# virtual time taken     %10.4f\n",
1300                              virttime);
1301
1302 #ifdef WATCHFUNCTIONS
1303   callback->printf_filtered (callback, "\nNumber of watched functions: %d\n",
1304                              ENDWL);
1305
1306   wcyc = 0;
1307
1308   for (w = 1; w <= ENDWL; w++)
1309     {
1310       callback->printf_filtered (callback, "WL = %s %8x\n",WLstr[w],WL[w]);
1311       callback->printf_filtered (callback, "  calls = %d, cycles = %d\n",
1312                                  WLcnts[w],WLcyc[w]);
1313
1314       if (WLcnts[w] != 0)
1315         callback->printf_filtered (callback,
1316                                    "  maxcpc = %d, mincpc = %d, avecpc = %d\n",
1317                                    WLmax[w],WLmin[w],WLcyc[w]/WLcnts[w]);
1318       wcyc += WLcyc[w];
1319     }
1320
1321   callback->printf_filtered (callback,
1322                              "Total cycles for watched functions: %d\n",wcyc);
1323 #endif
1324 }
1325
1326 static sim_cia
1327 mcore_pc_get (sim_cpu *cpu)
1328 {
1329   return cpu->regs.pc;
1330 }
1331
1332 static void
1333 mcore_pc_set (sim_cpu *cpu, sim_cia pc)
1334 {
1335   cpu->regs.pc = pc;
1336 }
1337
1338 static void
1339 free_state (SIM_DESC sd)
1340 {
1341   if (STATE_MODULES (sd) != NULL)
1342     sim_module_uninstall (sd);
1343   sim_cpu_free_all (sd);
1344   sim_state_free (sd);
1345 }
1346
1347 SIM_DESC
1348 sim_open (SIM_OPEN_KIND kind, host_callback *cb,
1349           struct bfd *abfd, char * const *argv)
1350 {
1351   int i;
1352   SIM_DESC sd = sim_state_alloc (kind, cb);
1353   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
1354
1355   /* Set default options before parsing user options.  */
1356   cb->syscall_map = cb_mcore_syscall_map;
1357
1358   /* The cpu data is kept in a separately allocated chunk of memory.  */
1359   if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
1360     {
1361       free_state (sd);
1362       return 0;
1363     }
1364
1365   if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
1366     {
1367       free_state (sd);
1368       return 0;
1369     }
1370
1371   /* The parser will print an error message for us, so we silently return.  */
1372   if (sim_parse_args (sd, argv) != SIM_RC_OK)
1373     {
1374       free_state (sd);
1375       return 0;
1376     }
1377
1378   /* Check for/establish the a reference program image.  */
1379   if (sim_analyze_program (sd, STATE_PROG_FILE (sd), abfd) != SIM_RC_OK)
1380     {
1381       free_state (sd);
1382       return 0;
1383     }
1384
1385   /* Configure/verify the target byte order and other runtime
1386      configuration options.  */
1387   if (sim_config (sd) != SIM_RC_OK)
1388     {
1389       sim_module_uninstall (sd);
1390       return 0;
1391     }
1392
1393   if (sim_post_argv_init (sd) != SIM_RC_OK)
1394     {
1395       /* Uninstall the modules to avoid memory leaks,
1396          file descriptor leaks, etc.  */
1397       sim_module_uninstall (sd);
1398       return 0;
1399     }
1400
1401   /* CPU specific initialization.  */
1402   for (i = 0; i < MAX_NR_PROCESSORS; ++i)
1403     {
1404       SIM_CPU *cpu = STATE_CPU (sd, i);
1405
1406       CPU_REG_FETCH (cpu) = mcore_reg_fetch;
1407       CPU_REG_STORE (cpu) = mcore_reg_store;
1408       CPU_PC_FETCH (cpu) = mcore_pc_get;
1409       CPU_PC_STORE (cpu) = mcore_pc_set;
1410
1411       set_initial_gprs (cpu);   /* Reset the GPR registers.  */
1412     }
1413
1414   /* Default to a 8 Mbyte (== 2^23) memory space.  */
1415   sim_do_commandf (sd, "memory-size %#x", DEFAULT_MEMORY_SIZE);
1416
1417   return sd;
1418 }
1419
1420 SIM_RC
1421 sim_create_inferior (SIM_DESC sd, struct bfd *prog_bfd,
1422                      char * const *argv, char * const *env)
1423 {
1424   SIM_CPU *cpu = STATE_CPU (sd, 0);
1425   char * const *avp;
1426   int nargs = 0;
1427   int nenv = 0;
1428   int s_length;
1429   int l;
1430   unsigned long strings;
1431   unsigned long pointers;
1432   unsigned long hi_stack;
1433
1434
1435   /* Set the initial register set.  */
1436   set_initial_gprs (cpu);
1437
1438   hi_stack = DEFAULT_MEMORY_SIZE - 4;
1439   CPU_PC_SET (cpu, bfd_get_start_address (prog_bfd));
1440
1441   /* Calculate the argument and environment strings.  */
1442   s_length = 0;
1443   nargs = 0;
1444   avp = argv;
1445   while (avp && *avp)
1446     {
1447       l = strlen (*avp) + 1;    /* include the null */
1448       s_length += (l + 3) & ~3; /* make it a 4 byte boundary */
1449       nargs++; avp++;
1450     }
1451
1452   nenv = 0;
1453   avp = env;
1454   while (avp && *avp)
1455     {
1456       l = strlen (*avp) + 1;    /* include the null */
1457       s_length += (l + 3) & ~ 3;/* make it a 4 byte boundary */
1458       nenv++; avp++;
1459     }
1460
1461   /* Claim some memory for the pointers and strings. */
1462   pointers = hi_stack - sizeof(word) * (nenv+1+nargs+1);
1463   pointers &= ~3;               /* must be 4-byte aligned */
1464   gr[0] = pointers;
1465
1466   strings = gr[0] - s_length;
1467   strings &= ~3;                /* want to make it 4-byte aligned */
1468   gr[0] = strings;
1469   /* dac fix, the stack address must be 8-byte aligned! */
1470   gr[0] = gr[0] - gr[0] % 8;
1471
1472   /* Loop through the arguments and fill them in.  */
1473   gr[PARM1] = nargs;
1474   if (nargs == 0)
1475     {
1476       /* No strings to fill in.  */
1477       gr[PARM2] = 0;
1478     }
1479   else
1480     {
1481       gr[PARM2] = pointers;
1482       avp = argv;
1483       while (avp && *avp)
1484         {
1485           /* Save where we're putting it.  */
1486           wlat (pointers, strings);
1487
1488           /* Copy the string.  */
1489           l = strlen (* avp) + 1;
1490           sim_core_write_buffer (sd, cpu, write_map, *avp, strings, l);
1491
1492           /* Bump the pointers.  */
1493           avp++;
1494           pointers += 4;
1495           strings += l+1;
1496         }
1497
1498       /* A null to finish the list.  */
1499       wlat (pointers, 0);
1500       pointers += 4;
1501     }
1502
1503   /* Now do the environment pointers.  */
1504   if (nenv == 0)
1505     {
1506       /* No strings to fill in.  */
1507       gr[PARM3] = 0;
1508     }
1509   else
1510     {
1511       gr[PARM3] = pointers;
1512       avp = env;
1513
1514       while (avp && *avp)
1515         {
1516           /* Save where we're putting it.  */
1517           wlat (pointers, strings);
1518
1519           /* Copy the string.  */
1520           l = strlen (* avp) + 1;
1521           sim_core_write_buffer (sd, cpu, write_map, *avp, strings, l);
1522
1523           /* Bump the pointers.  */
1524           avp++;
1525           pointers += 4;
1526           strings += l+1;
1527         }
1528
1529       /* A null to finish the list.  */
1530       wlat (pointers, 0);
1531       pointers += 4;
1532     }
1533
1534   return SIM_RC_OK;
1535 }
This page took 0.112262 seconds and 4 git commands to generate.