1
diff --git a/bfd/archures.c b/bfd/archures.c
2
index cd8500f..94f951a 100644
5
@@ -408,21 +408,8 @@ DESCRIPTION
7
.#define bfd_mach_xstormy16 1
8
. bfd_arch_msp430, {* Texas Instruments MSP430 architecture. *}
9
-.#define bfd_mach_msp11 11
10
-.#define bfd_mach_msp110 110
11
-.#define bfd_mach_msp12 12
12
-.#define bfd_mach_msp13 13
13
-.#define bfd_mach_msp14 14
14
-.#define bfd_mach_msp15 15
15
-.#define bfd_mach_msp16 16
16
-.#define bfd_mach_msp21 21
17
-.#define bfd_mach_msp31 31
18
-.#define bfd_mach_msp32 32
19
-.#define bfd_mach_msp33 33
20
-.#define bfd_mach_msp41 41
21
-.#define bfd_mach_msp42 42
22
-.#define bfd_mach_msp43 43
23
-.#define bfd_mach_msp44 44
24
+.#define bfd_mach_msp430 430
25
+.#define bfd_mach_msp430x 431
26
. bfd_arch_xc16x, {* Infineon's XC16X Series. *}
27
.#define bfd_mach_xc16x 1
28
.#define bfd_mach_xc16xl 2
29
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
30
index 2c795b6..e21ef7b 100644
33
@@ -2095,21 +2095,8 @@ enum bfd_architecture
35
#define bfd_mach_xstormy16 1
36
bfd_arch_msp430, /* Texas Instruments MSP430 architecture. */
37
-#define bfd_mach_msp11 11
38
-#define bfd_mach_msp110 110
39
-#define bfd_mach_msp12 12
40
-#define bfd_mach_msp13 13
41
-#define bfd_mach_msp14 14
42
-#define bfd_mach_msp15 15
43
-#define bfd_mach_msp16 16
44
-#define bfd_mach_msp21 21
45
-#define bfd_mach_msp31 31
46
-#define bfd_mach_msp32 32
47
-#define bfd_mach_msp33 33
48
-#define bfd_mach_msp41 41
49
-#define bfd_mach_msp42 42
50
-#define bfd_mach_msp43 43
51
-#define bfd_mach_msp44 44
52
+#define bfd_mach_msp430 430
53
+#define bfd_mach_msp430x 431
54
bfd_arch_xc16x, /* Infineon's XC16X Series. */
55
#define bfd_mach_xc16x 1
56
#define bfd_mach_xc16xl 2
57
@@ -4587,6 +4574,25 @@ This is the 5 bits of a value. */
58
BFD_RELOC_MSP430_16_BYTE,
59
BFD_RELOC_MSP430_2X_PCREL,
60
BFD_RELOC_MSP430_RL_PCREL,
61
+ BFD_RELOC_MSP430X_SRC_BYTE,
62
+ BFD_RELOC_MSP430X_SRC,
63
+ BFD_RELOC_MSP430X_DST_BYTE,
64
+ BFD_RELOC_MSP430X_DST,
65
+ BFD_RELOC_MSP430X_DST_2ND_BYTE,
66
+ BFD_RELOC_MSP430X_DST_2ND,
67
+ BFD_RELOC_MSP430X_PCREL_SRC_BYTE,
68
+ BFD_RELOC_MSP430X_PCREL_SRC,
69
+ BFD_RELOC_MSP430X_PCREL_DST_BYTE,
70
+ BFD_RELOC_MSP430X_PCREL_DST,
71
+ BFD_RELOC_MSP430X_PCREL_DST_2ND,
72
+ BFD_RELOC_MSP430X_PCREL_DST_2ND_BYTE,
73
+ BFD_RELOC_MSP430X_S_BYTE,
74
+ BFD_RELOC_MSP430X_S,
75
+ BFD_RELOC_MSP430X_D_BYTE,
76
+ BFD_RELOC_MSP430X_D,
77
+ BFD_RELOC_MSP430X_PCREL_D,
78
+ BFD_RELOC_MSP430X_INDXD,
79
+ BFD_RELOC_MSP430X_PCREL_INDXD,
81
/* IQ2000 Relocations. */
82
BFD_RELOC_IQ2000_OFFSET_16,
83
diff --git a/bfd/cpu-msp430.c b/bfd/cpu-msp430.c
84
index 63c301a..9e9fcdd 100644
85
--- a/bfd/cpu-msp430.c
86
+++ b/bfd/cpu-msp430.c
91
-static const bfd_arch_info_type *compatible
92
- PARAMS ((const bfd_arch_info_type *, const bfd_arch_info_type *));
94
-#define N(addr_bits, machine, print, default, next) \
96
- 16, /* 16 bits in a word. */ \
97
- addr_bits, /* Bits in an address. */ \
98
- 8, /* 8 bits in a byte. */ \
100
- machine, /* Machine number. */ \
101
- "msp430", /* Architecture name. */ \
102
- print, /* Printable name. */ \
103
- 1, /* Section align power. */ \
104
- default, /* The default machine. */ \
106
- bfd_default_scan, \
110
-static const bfd_arch_info_type arch_info_struct[] =
113
- N (16, bfd_mach_msp11, "msp:11", FALSE, & arch_info_struct[1]),
116
- N (16, bfd_mach_msp110, "msp:110", FALSE, & arch_info_struct[2]),
119
- N (16, bfd_mach_msp12, "msp:12", FALSE, & arch_info_struct[3]),
122
- N (16, bfd_mach_msp13, "msp:13", FALSE, & arch_info_struct[4]),
125
- N (16, bfd_mach_msp14, "msp:14", FALSE, & arch_info_struct[5]),
128
- N (16, bfd_mach_msp15, "msp:15", FALSE, & arch_info_struct[6]),
131
- N (16, bfd_mach_msp16, "msp:16", FALSE, & arch_info_struct[7]),
134
- N (16, bfd_mach_msp21, "msp:21", FALSE, & arch_info_struct[8]),
137
- N (16, bfd_mach_msp31, "msp:31", FALSE, & arch_info_struct[9]),
140
- N (16, bfd_mach_msp32, "msp:32", FALSE, & arch_info_struct[10]),
143
- N (16, bfd_mach_msp33, "msp:33", FALSE, & arch_info_struct[11]),
146
- N (16, bfd_mach_msp41, "msp:41", FALSE, & arch_info_struct[12]),
149
- N (16, bfd_mach_msp42, "msp:42", FALSE, & arch_info_struct[13]),
152
- N (16, bfd_mach_msp43, "msp:43", FALSE, & arch_info_struct[14]),
155
- N (16, bfd_mach_msp43, "msp:44", FALSE, NULL)
158
-const bfd_arch_info_type bfd_msp430_arch =
159
- N (16, bfd_mach_msp14, "msp:14", TRUE, & arch_info_struct[0]);
161
/* This routine is provided two arch_infos and works out which MSP
162
machine which would be compatible with both and returns a pointer
163
- to its info structure. */
165
+ to its info structure. */
166
static const bfd_arch_info_type *
168
- const bfd_arch_info_type * a;
169
- const bfd_arch_info_type * b;
170
+compatible (const bfd_arch_info_type *a,
171
+ const bfd_arch_info_type *b)
173
- /* If a & b are for different architectures we can do nothing. */
174
+ /* If a & b are for different architectures we can do nothing */
175
if (a->arch != b->arch)
178
@@ -111,3 +39,35 @@ compatible (a,b)
183
+/* Architecture for MSP430X and MSP430XV2 */
184
+static const bfd_arch_info_type bfd_msp430x_arch = {
185
+ 16, /* 16 bits in a word */
186
+ 20, /* 20 bits in an address */
187
+ 8, /* 8 bits in a byte */
189
+ bfd_mach_msp430x, /* Machine number */
190
+ "msp430", /* Architecture name. */
191
+ "msp430:430X", /* Printable name */
192
+ 1, /* Section align power */
193
+ FALSE, /* The default machine */
199
+/* Architecture for MSP430 */
200
+const bfd_arch_info_type bfd_msp430_arch = {
201
+ 16, /* 16 bits in a word */
202
+ 16, /* 16 bits in an address */
203
+ 8, /* 8 bits in a byte */
205
+ bfd_mach_msp430, /* Machine number */
206
+ "msp430", /* Architecture name */
207
+ "msp430:430", /* Printable name */
208
+ 1, /* Section align power */
209
+ TRUE, /* The default machine */
214
diff --git a/bfd/elf32-msp430.c b/bfd/elf32-msp430.c
215
index 9a5fb2a..a2fc8c1 100644
216
--- a/bfd/elf32-msp430.c
217
+++ b/bfd/elf32-msp430.c
218
@@ -90,7 +90,7 @@ static reloc_howto_type elf_msp430_howto_table[] =
219
0xffff, /* dst_mask */
220
FALSE), /* pcrel_offset */
222
- /* A 16 bit absolute relocation for command address. */
223
+ /* A 16 bit PC relative relocation for command address. */
224
HOWTO (R_MSP430_16_PCREL, /* type */
226
1, /* size (0 = byte, 1 = short, 2 = long) */
227
@@ -120,7 +120,7 @@ static reloc_howto_type elf_msp430_howto_table[] =
228
0xffff, /* dst_mask */
229
FALSE), /* pcrel_offset */
231
- /* A 16 bit absolute relocation for command address. */
232
+ /* A 16 bit PC relative relocation, byte operations. */
233
HOWTO (R_MSP430_16_PCREL_BYTE,/* type */
235
1, /* size (0 = byte, 1 = short, 2 = long) */
236
@@ -163,7 +163,292 @@ static reloc_howto_type elf_msp430_howto_table[] =
237
FALSE, /* partial_inplace */
239
0xffff, /* dst_mask */
240
- TRUE) /* pcrel_offset */
241
+ TRUE), /* pcrel_offset */
243
+ /* A 20 bit msp430x absolute src operand relocation, byte operations */
244
+ HOWTO (R_MSP430X_SRC_BYTE, /* type */
245
+ 0, /* rightshift */
246
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
248
+ FALSE, /* pc_relative */
250
+ complain_overflow_dont,/* complain_on_overflow */
251
+ bfd_elf_generic_reloc, /* special_function */
252
+ "R_MSP430X_SRC_BYTE", /* name */
253
+ FALSE, /* partial_inplace */
254
+ 0xfffff, /* src_mask */
256
+ FALSE), /* pcrel_offset */
258
+ /* A 20 bit msp430x absolute src operand relocation */
259
+ HOWTO (R_MSP430X_SRC, /* type */
260
+ 0, /* rightshift */
261
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
263
+ FALSE, /* pc_relative */
265
+ complain_overflow_dont,/* complain_on_overflow */
266
+ bfd_elf_generic_reloc, /* special_function */
267
+ "R_MSP430X_SRC", /* name */
268
+ FALSE, /* partial_inplace */
269
+ 0xfffff, /* src_mask */
271
+ FALSE), /* pcrel_offset */
273
+ /* A 20 bit msp430x absolute dst operand relocation, src is register mode, byte operations */
274
+ HOWTO (R_MSP430X_DST_BYTE, /* type */
275
+ 0, /* rightshift */
276
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
278
+ FALSE, /* pc_relative */
280
+ complain_overflow_dont,/* complain_on_overflow */
281
+ bfd_elf_generic_reloc, /* special_function */
282
+ "R_MSP430X_DST_BYTE", /* name */
283
+ FALSE, /* partial_inplace */
285
+ 0xfffff, /* dst_mask */
286
+ FALSE), /* pcrel_offset */
288
+ /* A 20 bit msp430x absolute dst operand relocation, src is register mode */
289
+ HOWTO (R_MSP430X_DST, /* type */
290
+ 0, /* rightshift */
291
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
293
+ FALSE, /* pc_relative */
295
+ complain_overflow_dont,/* complain_on_overflow */
296
+ bfd_elf_generic_reloc, /* special_function */
297
+ "R_MSP430X_DST", /* name */
298
+ FALSE, /* partial_inplace */
300
+ 0xfffff, /* dst_mask */
301
+ FALSE), /* pcrel_offset */
303
+ /* A 20 bit msp430x absolute dst operand relocation, byte operations */
304
+ HOWTO (R_MSP430X_DST_2ND_BYTE, /* type */
305
+ 0, /* rightshift */
306
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
308
+ FALSE, /* pc_relative */
310
+ complain_overflow_dont,/* complain_on_overflow */
311
+ bfd_elf_generic_reloc, /* special_function */
312
+ "R_MSP430X_DST_2ND_BYTE", /* name */
313
+ FALSE, /* partial_inplace */
315
+ 0xfffff, /* dst_mask */
316
+ FALSE), /* pcrel_offset */
318
+ /* A 20 bit msp430x absolute dst operand relocation */
319
+ HOWTO (R_MSP430X_DST_2ND, /* type */
320
+ 0, /* rightshift */
321
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
323
+ FALSE, /* pc_relative */
325
+ complain_overflow_dont,/* complain_on_overflow */
326
+ bfd_elf_generic_reloc, /* special_function */
327
+ "R_MSP430X_DST_2ND", /* name */
328
+ FALSE, /* partial_inplace */
330
+ 0xfffff, /* dst_mask */
331
+ FALSE), /* pcrel_offset */
333
+ /* A 20 bit msp430x PC relative src operand relocation, byte operations */
334
+ HOWTO (R_MSP430X_PCREL_SRC_BYTE, /* type */
335
+ 0, /* rightshift */
336
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
338
+ TRUE, /* pc_relative */
340
+ complain_overflow_dont,/* complain_on_overflow */
341
+ bfd_elf_generic_reloc, /* special_function */
342
+ "R_MSP430X_PCREL_SRC_BYTE", /* name */
343
+ FALSE, /* partial_inplace */
344
+ 0xfffff, /* src_mask */
346
+ TRUE), /* pcrel_offset */
348
+ /* A 20 bit msp430x PC relative src operand relocation */
349
+ HOWTO (R_MSP430X_PCREL_SRC, /* type */
350
+ 0, /* rightshift */
351
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
353
+ TRUE, /* pc_relative */
355
+ complain_overflow_dont,/* complain_on_overflow */
356
+ bfd_elf_generic_reloc, /* special_function */
357
+ "R_MSP430X_PCREL_SRC", /* name */
358
+ FALSE, /* partial_inplace */
359
+ 0xfffff, /* src_mask */
361
+ TRUE), /* pcrel_offset */
363
+ /* A 20 bit msp430x PC relative dst operand relocation, src is register mode, byte operations */
364
+ HOWTO (R_MSP430X_PCREL_DST_BYTE, /* type */
365
+ 0, /* rightshift */
366
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
368
+ TRUE, /* pc_relative */
370
+ complain_overflow_dont,/* complain_on_overflow */
371
+ bfd_elf_generic_reloc, /* special_function */
372
+ "R_MSP430X_PCREL_DST_BYTE", /* name */
373
+ FALSE, /* partial_inplace */
375
+ 0xfffff, /* dst_mask */
376
+ TRUE), /* pcrel_offset */
378
+ /* A 20 bit msp430x PC relative dst operand relocation, src is register mode */
379
+ HOWTO (R_MSP430X_PCREL_DST, /* type */
380
+ 0, /* rightshift */
381
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
383
+ TRUE, /* pc_relative */
385
+ complain_overflow_dont,/* complain_on_overflow */
386
+ bfd_elf_generic_reloc, /* special_function */
387
+ "R_MSP430X_PCREL_DST", /* name */
388
+ FALSE, /* partial_inplace */
390
+ 0xfffff, /* dst_mask */
391
+ TRUE), /* pcrel_offset */
393
+ /* A 20 bit msp430x PC relative dst operand relocation, byte operations */
394
+ HOWTO (R_MSP430X_PCREL_DST_2ND_BYTE, /* type */
395
+ 0, /* rightshift */
396
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
398
+ TRUE, /* pc_relative */
400
+ complain_overflow_dont,/* complain_on_overflow */
401
+ bfd_elf_generic_reloc, /* special_function */
402
+ "R_MSP430X_PCREL_DST_2ND_BYTE", /* name */
403
+ FALSE, /* partial_inplace */
405
+ 0xfffff, /* dst_mask */
406
+ TRUE), /* pcrel_offset */
408
+ /* A 20 bit msp430x PC relative dst operand relocation */
409
+ HOWTO (R_MSP430X_PCREL_DST_2ND, /* type */
410
+ 0, /* rightshift */
411
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
413
+ TRUE, /* pc_relative */
415
+ complain_overflow_dont,/* complain_on_overflow */
416
+ bfd_elf_generic_reloc, /* special_function */
417
+ "R_MSP430X_PCREL_DST_2ND", /* name */
418
+ FALSE, /* partial_inplace */
420
+ 0xfffff, /* dst_mask */
421
+ TRUE), /* pcrel_offset */
423
+ /* A 20 bit msp430x address instructions immediate src operand relocation */
424
+ HOWTO (R_MSP430X_S_BYTE, /* type */
425
+ 0, /* rightshift */
426
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
428
+ FALSE, /* pc_relative */
430
+ complain_overflow_dont,/* complain_on_overflow */
431
+ bfd_elf_generic_reloc, /* special_function */
432
+ "R_MSP430X_S_BYTE", /* name */
433
+ FALSE, /* partial_inplace */
434
+ 0xfffff, /* src_mask */
436
+ FALSE), /* pcrel_offset */
438
+ /* A 20 bit msp430x address instructions absolute src operand relocation */
439
+ HOWTO (R_MSP430X_S, /* type */
440
+ 0, /* rightshift */
441
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
443
+ FALSE, /* pc_relative */
445
+ complain_overflow_dont,/* complain_on_overflow */
446
+ bfd_elf_generic_reloc, /* special_function */
447
+ "R_MSP430X_S", /* name */
448
+ FALSE, /* partial_inplace */
449
+ 0xfffff, /* src_mask */
451
+ FALSE), /* pcrel_offset */
453
+ /* A 20 bit msp430x address instructions immediate dst operand relocation */
454
+ HOWTO (R_MSP430X_D_BYTE, /* type */
455
+ 0, /* rightshift */
456
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
458
+ FALSE, /* pc_relative */
460
+ complain_overflow_dont,/* complain_on_overflow */
461
+ bfd_elf_generic_reloc, /* special_function */
462
+ "R_MSP430X_D_BYTE", /* name */
463
+ FALSE, /* partial_inplace */
465
+ 0xfffff, /* dst_mask */
466
+ FALSE), /* pcrel_offset */
468
+ /* A 20 bit msp430x address instructions absolute dst operand relocation */
469
+ HOWTO (R_MSP430X_D, /* type */
470
+ 0, /* rightshift */
471
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
473
+ FALSE, /* pc_relative */
475
+ complain_overflow_dont,/* complain_on_overflow */
476
+ bfd_elf_generic_reloc, /* special_function */
477
+ "R_MSP430X_D", /* name */
478
+ FALSE, /* partial_inplace */
480
+ 0xfffff, /* dst_mask */
481
+ FALSE), /* pcrel_offset */
483
+ /* A 20 bit msp430x address instructions absolute dst operand relocation */
484
+ HOWTO (R_MSP430X_PCREL_D, /* type */
485
+ 0, /* rightshift */
486
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
488
+ TRUE, /* pc_relative */
490
+ complain_overflow_dont,/* complain_on_overflow */
491
+ bfd_elf_generic_reloc, /* special_function */
492
+ "R_MSP430X_PCREL_D", /* name */
493
+ FALSE, /* partial_inplace */
495
+ 0xfffff, /* dst_mask */
496
+ TRUE), /* pcrel_offset */
498
+ /* A 16 bit msp430x relocation *** for msp430x calla 16-bit PC-relative index ***/
499
+ HOWTO (R_MSP430X_PCREL_INDXD, /* type */
500
+ 0, /* rightshift */
501
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
503
+ TRUE, /* pc_relative */
505
+ complain_overflow_dont,/* complain_on_overflow */
506
+ bfd_elf_generic_reloc, /* special_function */
507
+ "R_MSP430X_PCREL_INDXD", /* name */
508
+ FALSE, /* partial_inplace */
509
+ 0xffff, /* src_mask */
510
+ 0xffff, /* dst_mask */
511
+ TRUE), /* pcrel_offset */
513
+ /* A 16 bit msp430x relocation *** for msp430x bra/calla 16-bit index ***/
514
+ HOWTO (R_MSP430X_INDXD, /* type */
515
+ 0, /* rightshift */
516
+ 1, /* size (0 = byte, 1 = short, 2 = long) */
518
+ FALSE, /* pc_relative */
520
+ complain_overflow_dont,/* complain_on_overflow */
521
+ bfd_elf_generic_reloc, /* special_function */
522
+ "R_MSP430X_INDXD", /* name */
523
+ FALSE, /* partial_inplace */
524
+ 0xffff, /* src_mask */
525
+ 0xffff, /* dst_mask */
526
+ FALSE), /* pcrel_offset */
529
/* Map BFD reloc types to MSP430 ELF reloc types. */
530
@@ -185,7 +470,29 @@ static const struct msp430_reloc_map msp430_reloc_map[] =
531
{BFD_RELOC_MSP430_16_PCREL_BYTE, R_MSP430_16_PCREL_BYTE},
532
{BFD_RELOC_MSP430_16_BYTE, R_MSP430_16_BYTE},
533
{BFD_RELOC_MSP430_2X_PCREL, R_MSP430_2X_PCREL},
534
- {BFD_RELOC_MSP430_RL_PCREL, R_MSP430_RL_PCREL}
535
+ {BFD_RELOC_MSP430_RL_PCREL, R_MSP430_RL_PCREL},
537
+ {BFD_RELOC_MSP430X_SRC_BYTE, R_MSP430X_SRC_BYTE},
538
+ {BFD_RELOC_MSP430X_SRC, R_MSP430X_SRC},
539
+ {BFD_RELOC_MSP430X_DST_BYTE, R_MSP430X_DST_BYTE},
540
+ {BFD_RELOC_MSP430X_DST, R_MSP430X_DST},
541
+ {BFD_RELOC_MSP430X_DST_2ND_BYTE, R_MSP430X_DST_2ND_BYTE},
542
+ {BFD_RELOC_MSP430X_DST_2ND, R_MSP430X_DST_2ND},
544
+ {BFD_RELOC_MSP430X_PCREL_SRC_BYTE, R_MSP430X_PCREL_SRC_BYTE},
545
+ {BFD_RELOC_MSP430X_PCREL_SRC, R_MSP430X_PCREL_SRC},
546
+ {BFD_RELOC_MSP430X_PCREL_DST_BYTE, R_MSP430X_PCREL_DST_BYTE},
547
+ {BFD_RELOC_MSP430X_PCREL_DST, R_MSP430X_PCREL_DST},
548
+ {BFD_RELOC_MSP430X_PCREL_DST_2ND_BYTE, R_MSP430X_PCREL_DST_2ND_BYTE},
549
+ {BFD_RELOC_MSP430X_PCREL_DST_2ND, R_MSP430X_PCREL_DST_2ND},
551
+ {BFD_RELOC_MSP430X_S_BYTE, R_MSP430X_S_BYTE},
552
+ {BFD_RELOC_MSP430X_S, R_MSP430X_S},
553
+ {BFD_RELOC_MSP430X_D_BYTE, R_MSP430X_D_BYTE},
554
+ {BFD_RELOC_MSP430X_D, R_MSP430X_D},
555
+ {BFD_RELOC_MSP430X_PCREL_D, R_MSP430X_PCREL_D},
556
+ {BFD_RELOC_MSP430X_INDXD, R_MSP430X_INDXD},
557
+ {BFD_RELOC_MSP430X_PCREL_INDXD, R_MSP430X_PCREL_INDXD},
560
static reloc_howto_type *
561
@@ -207,10 +514,7 @@ bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
566
- i < (sizeof (elf_msp430_howto_table)
567
- / sizeof (elf_msp430_howto_table[0]));
569
+ for (i = 0; i < ARRAY_SIZE (elf_msp430_howto_table); i++)
570
if (elf_msp430_howto_table[i].name != NULL
571
&& strcasecmp (elf_msp430_howto_table[i].name, r_name) == 0)
572
return &elf_msp430_howto_table[i];
573
@@ -282,18 +586,44 @@ msp430_final_link_relocate (reloc_howto_type * howto, bfd * input_bfd,
575
bfd_reloc_status_type r = bfd_reloc_ok;
577
- bfd_signed_vma srel;
578
+ bfd_signed_vma srel = 0;
580
- switch (howto->type)
581
+ if (howto->type > R_MSP430_32 && howto->type < R_MSP430_max)
583
- case R_MSP430_10_PCREL:
584
contents += rel->r_offset;
585
srel = (bfd_signed_vma) relocation;
586
srel += rel->r_addend;
587
- srel -= rel->r_offset;
589
+ if(howto->pc_relative)
591
+ srel -= rel->r_offset;
592
+ srel -= (input_section->output_section->vma +
593
+ input_section->output_offset);
596
+ switch (howto->type)
598
+ case R_MSP430X_PCREL_D: // PC relative dst operand of calla
599
+ case R_MSP430X_PCREL_INDXD: // 16-bit idx in mova/bra instruction PC relative (symbolic) mode operand
600
+ srel -= 2; // operand located 2 bytes after opcode
602
+ case R_MSP430X_PCREL_SRC: // PC-relative 20-bit address operand
603
+ case R_MSP430X_PCREL_SRC_BYTE:
604
+ case R_MSP430X_PCREL_DST:
605
+ case R_MSP430X_PCREL_DST_BYTE:
606
+ srel -= 4; // operand located 4 bytes after opcode
608
+ case R_MSP430X_PCREL_DST_2ND:
609
+ case R_MSP430X_PCREL_DST_2ND_BYTE:
610
+ srel -= 6; // operand located 6 bytes after opcode
615
+ switch (howto->type)
617
+ case R_MSP430_10_PCREL:
618
srel -= 2; /* Branch instructions add 2 to the PC... */
619
- srel -= (input_section->output_section->vma +
620
- input_section->output_offset);
623
return bfd_reloc_outofrange;
624
@@ -311,13 +641,7 @@ msp430_final_link_relocate (reloc_howto_type * howto, bfd * input_bfd,
627
case R_MSP430_2X_PCREL:
628
- contents += rel->r_offset;
629
- srel = (bfd_signed_vma) relocation;
630
- srel += rel->r_addend;
631
- srel -= rel->r_offset;
632
srel -= 2; /* Branch instructions add 2 to the PC... */
633
- srel -= (input_section->output_section->vma +
634
- input_section->output_offset);
637
return bfd_reloc_outofrange;
638
@@ -341,13 +665,7 @@ msp430_final_link_relocate (reloc_howto_type * howto, bfd * input_bfd,
640
case R_MSP430_16_PCREL:
641
case R_MSP430_RL_PCREL:
642
- contents += rel->r_offset;
643
- srel = (bfd_signed_vma) relocation;
644
- srel += rel->r_addend;
645
- srel -= rel->r_offset;
646
/* Only branch instructions add 2 to the PC... */
647
- srel -= (input_section->output_section->vma +
648
- input_section->output_offset);
651
return bfd_reloc_outofrange;
652
@@ -356,35 +674,138 @@ msp430_final_link_relocate (reloc_howto_type * howto, bfd * input_bfd,
655
case R_MSP430_16_PCREL_BYTE:
656
- contents += rel->r_offset;
657
- srel = (bfd_signed_vma) relocation;
658
- srel += rel->r_addend;
659
- srel -= rel->r_offset;
660
/* Only branch instructions add 2 to the PC... */
661
- srel -= (input_section->output_section->vma +
662
- input_section->output_offset);
664
bfd_put_16 (input_bfd, srel & 0xffff, contents);
667
case R_MSP430_16_BYTE:
668
- contents += rel->r_offset;
669
- srel = (bfd_signed_vma) relocation;
670
- srel += rel->r_addend;
671
bfd_put_16 (input_bfd, srel & 0xffff, contents);
675
- contents += rel->r_offset;
676
- srel = (bfd_signed_vma) relocation;
677
- srel += rel->r_addend;
680
return bfd_reloc_notsupported;
682
bfd_put_16 (input_bfd, srel & 0xffff, contents);
685
+ case R_MSP430X_SRC: // address operand
686
+ case R_MSP430X_PCREL_SRC: // PC-relative address operand
688
+ // 20 bit reloc for msp430x
689
+ // src in Non-register mode extended instructions,
690
+ // imm/abs in bra instruction
692
+ // src(19:16) located at positions 10:7 of extension word
693
+ // src(15:0) located just after opcode
695
+ if (srel & 1) // odd address
696
+ return bfd_reloc_notsupported;
697
+ /* and fall trough, no break here!!! */
698
+ case R_MSP430X_SRC_BYTE: // byte instructions or immediate operand
699
+ case R_MSP430X_PCREL_SRC_BYTE:
700
+ x = bfd_get_16 (input_bfd, contents);
701
+ /* 4 most-significant bits */
702
+ x = (x & 0xf87f) | ((srel >> 9) & 0x0780);
703
+ bfd_put_16 (input_bfd, x, contents);
704
+ /* 16 least-significant bits */
705
+ bfd_put_16 (input_bfd, srel & 0xffff, contents + 4);
708
+ case R_MSP430X_DST: // address operand
709
+ case R_MSP430X_PCREL_DST:
711
+ // 20 bit reloc for msp430x
712
+ // dst in Non-register mode extended instructions,
713
+ // imm/abs/20-bit idx in calla instruction
715
+ // dst(19:16) located at positions 3:0 of extension word
716
+ // dst(15:0) located just after opcode
718
+ if (srel & 1) // odd address
719
+ return bfd_reloc_notsupported;
720
+ /* and fall trough, no break here!!! */
721
+ case R_MSP430X_DST_BYTE: // byte instructions or immediate operand
722
+ case R_MSP430X_PCREL_DST_BYTE:
723
+ x = bfd_get_16 (input_bfd, contents);
724
+ /* 4 most-significant bits */
725
+ x = (x & 0xfff0) | ((srel >> 16) & 0x000f);
726
+ bfd_put_16 (input_bfd, x, contents);
727
+ /* 16 least-significant bits */
728
+ bfd_put_16 (input_bfd, srel & 0xffff, contents + 4);
731
+ case R_MSP430X_DST_2ND: // address operand
732
+ case R_MSP430X_PCREL_DST_2ND:
734
+ // 20 bit reloc for msp430x
735
+ // dst in Non-register mode extended instructions,
737
+ // dst(19:16) located at positions 3:0 of extension word
738
+ // dst(15:0) located after src(15:0)
740
+ if (srel & 1) // odd address
741
+ return bfd_reloc_notsupported;
742
+ /* and fall trough, no break here!!! */
743
+ case R_MSP430X_DST_2ND_BYTE: // byte instructions or immediate operand
744
+ case R_MSP430X_PCREL_DST_2ND_BYTE:
745
+ x = bfd_get_16 (input_bfd, contents);
746
+ /* 4 most-significant bits */
747
+ x = (x & 0xfff0) | ((srel >> 16) & 0x000f);
748
+ bfd_put_16 (input_bfd, x, contents);
749
+ /* 16 least-significant bits */
750
+ bfd_put_16 (input_bfd, srel & 0xffff, contents + 6);
753
+ case R_MSP430X_S: // absolute src operand of address instructions
754
+ // 20 bit reloc for msp430x
756
+ // src(19:16) located at positions 11:8 of opcode
757
+ // src(15:0) located just after opcode
759
+ if (srel & 1) //odd address
760
+ return bfd_reloc_notsupported;
761
+ /* and fall trough, no break here!!! */
762
+ case R_MSP430X_S_BYTE: // immediate src operand of address instructions
763
+ x = bfd_get_16 (input_bfd, contents);
764
+ /* 4 most-significant bits */
765
+ x = (x & 0xf0ff) | ((srel >> 8) & 0x0f00);
766
+ bfd_put_16 (input_bfd, x, contents);
767
+ /* 16 least-significant bits */
768
+ bfd_put_16 (input_bfd, srel & 0xffff, contents + 2);
771
+ case R_MSP430X_D: // absolute dst operand of address instructions
772
+ case R_MSP430X_PCREL_D: // PC relative dst operand of calla
773
+ // 20 bit reloc for msp430x,
775
+ // dst(19:16) located at positions 3:0 of opcode
776
+ // dst(15:0) located just after opcode
778
+ if (srel & 1) //odd address
779
+ return bfd_reloc_notsupported;
780
+ /* and fall trough, no break here!!! */
781
+ case R_MSP430X_D_BYTE: //immediate dst operand of address instructions
783
+ x = bfd_get_16 (input_bfd, contents);
784
+ /* 4 most-significant bits */
785
+ x = (x & 0xfff0) | ((srel >> 16) & 0x000f);
786
+ bfd_put_16 (input_bfd, x, contents);
787
+ /* 16 least-significant bits */
788
+ bfd_put_16 (input_bfd, srel & 0xffff, contents + 2);
791
+ case R_MSP430X_PCREL_INDXD: // 16-bit idx in mova/bra instruction PC relative (symbolic) mode operand
793
+ if (srel & 1) //odd address
794
+ return bfd_reloc_notsupported;
795
+ case R_MSP430X_INDXD: // 16-bit idx in calla/mova/bra instruction
798
+ bfd_put_16 (input_bfd, x, contents + 2); //16 least-significant bits
802
r = _bfd_final_link_relocate (howto, input_bfd, input_section,
803
contents, rel->r_offset,
804
@@ -517,150 +938,54 @@ elf32_msp430_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
808
-bfd_elf_msp430_final_write_processing (bfd * abfd,
809
- bfd_boolean linker ATTRIBUTE_UNUSED)
810
+msp430_elf_backend_final_write_processing (bfd * abfd,
811
+ bfd_boolean linker ATTRIBUTE_UNUSED)
814
+ Elf_Internal_Ehdr * i_ehdrp;
815
+ unsigned long flags;
817
+ i_ehdrp = elf_elfheader (abfd);
818
+ i_ehdrp->e_machine = EM_MSP430;
820
switch (bfd_get_mach (abfd))
823
- case bfd_mach_msp110:
824
- val = E_MSP430_MACH_MSP430x11x1;
827
- case bfd_mach_msp11:
828
- val = E_MSP430_MACH_MSP430x11;
831
- case bfd_mach_msp12:
832
- val = E_MSP430_MACH_MSP430x12;
835
- case bfd_mach_msp13:
836
- val = E_MSP430_MACH_MSP430x13;
839
- case bfd_mach_msp14:
840
- val = E_MSP430_MACH_MSP430x14;
843
- case bfd_mach_msp15:
844
- val = E_MSP430_MACH_MSP430x15;
847
- case bfd_mach_msp16:
848
- val = E_MSP430_MACH_MSP430x16;
851
- case bfd_mach_msp31:
852
- val = E_MSP430_MACH_MSP430x31;
855
- case bfd_mach_msp32:
856
- val = E_MSP430_MACH_MSP430x32;
859
- case bfd_mach_msp33:
860
- val = E_MSP430_MACH_MSP430x33;
863
- case bfd_mach_msp41:
864
- val = E_MSP430_MACH_MSP430x41;
867
- case bfd_mach_msp42:
868
- val = E_MSP430_MACH_MSP430x42;
871
- case bfd_mach_msp43:
872
- val = E_MSP430_MACH_MSP430x43;
873
+ case bfd_mach_msp430:
874
+ flags = EF_MSP430_ARCH_430;
877
- case bfd_mach_msp44:
878
- val = E_MSP430_MACH_MSP430x44;
879
+ case bfd_mach_msp430x:
880
+ flags = EF_MSP430_ARCH_430X;
884
- elf_elfheader (abfd)->e_machine = EM_MSP430;
885
- elf_elfheader (abfd)->e_flags &= ~EF_MSP430_MACH;
886
- elf_elfheader (abfd)->e_flags |= val;
887
+ i_ehdrp->e_flags = EF_MSP430_UNIARCH | flags;
890
/* Set the right machine number. */
893
-elf32_msp430_object_p (bfd * abfd)
894
+msp430_elf_backend_object_p (bfd * abfd ATTRIBUTE_UNUSED)
896
- int e_set = bfd_mach_msp14;
898
- if (elf_elfheader (abfd)->e_machine == EM_MSP430
899
- || elf_elfheader (abfd)->e_machine == EM_MSP430_OLD)
901
- int e_mach = elf_elfheader (abfd)->e_flags & EF_MSP430_MACH;
906
- case E_MSP430_MACH_MSP430x11:
907
- e_set = bfd_mach_msp11;
910
- case E_MSP430_MACH_MSP430x11x1:
911
- e_set = bfd_mach_msp110;
914
- case E_MSP430_MACH_MSP430x12:
915
- e_set = bfd_mach_msp12;
918
- case E_MSP430_MACH_MSP430x13:
919
- e_set = bfd_mach_msp13;
922
- case E_MSP430_MACH_MSP430x14:
923
- e_set = bfd_mach_msp14;
926
- case E_MSP430_MACH_MSP430x15:
927
- e_set = bfd_mach_msp15;
930
- case E_MSP430_MACH_MSP430x16:
931
- e_set = bfd_mach_msp16;
934
- case E_MSP430_MACH_MSP430x31:
935
- e_set = bfd_mach_msp31;
938
- case E_MSP430_MACH_MSP430x32:
939
- e_set = bfd_mach_msp32;
942
- case E_MSP430_MACH_MSP430x33:
943
- e_set = bfd_mach_msp33;
946
- case E_MSP430_MACH_MSP430x41:
947
- e_set = bfd_mach_msp41;
950
- case E_MSP430_MACH_MSP430x42:
951
- e_set = bfd_mach_msp42;
954
- case E_MSP430_MACH_MSP430x43:
955
- e_set = bfd_mach_msp43;
958
- case E_MSP430_MACH_MSP430x44:
959
- e_set = bfd_mach_msp44;
964
- return bfd_default_set_arch_mach (abfd, bfd_arch_msp430, e_set);
965
+ Elf_Internal_Ehdr * i_ehdrp;
968
+ i_ehdrp = elf_elfheader (abfd);
969
+ if (EM_MSP430 != i_ehdrp->e_machine)
971
+ if (EF_MSP430_UNIARCH & i_ehdrp->e_flags) {
972
+ switch (i_ehdrp->e_flags & EF_MSP430_ARCH)
975
+ case EF_MSP430_ARCH_430:
976
+ bfd_mach = bfd_mach_msp430;
978
+ case EF_MSP430_ARCH_430X:
979
+ bfd_mach = bfd_mach_msp430x;
983
+ bfd_mach = bfd_mach_msp430;
985
+ return bfd_default_set_arch_mach (abfd, bfd_arch_msp430, bfd_mach);
988
/* These functions handle relaxing for the msp430.
989
@@ -1167,13 +1492,12 @@ error_return:
990
#define TARGET_LITTLE_NAME "elf32-msp430"
992
#define elf_info_to_howto msp430_info_to_howto_rela
993
-#define elf_info_to_howto_rel NULL
994
#define elf_backend_relocate_section elf32_msp430_relocate_section
995
#define elf_backend_check_relocs elf32_msp430_check_relocs
996
#define elf_backend_can_gc_sections 1
997
-#define elf_backend_final_write_processing bfd_elf_msp430_final_write_processing
998
-#define elf_backend_object_p elf32_msp430_object_p
999
#define elf_backend_post_process_headers _bfd_elf_set_osabi
1000
#define bfd_elf32_bfd_relax_section msp430_elf_relax_section
1001
+#define elf_backend_final_write_processing msp430_elf_backend_final_write_processing
1002
+#define elf_backend_object_p msp430_elf_backend_object_p
1004
#include "elf32-target.h"
1005
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
1006
index 2e7df4f..b18acf2 100644
1009
@@ -2179,6 +2179,25 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
1010
"BFD_RELOC_MSP430_16_BYTE",
1011
"BFD_RELOC_MSP430_2X_PCREL",
1012
"BFD_RELOC_MSP430_RL_PCREL",
1013
+ "BFD_RELOC_MSP430X_SRC_BYTE",
1014
+ "BFD_RELOC_MSP430X_SRC",
1015
+ "BFD_RELOC_MSP430X_DST_BYTE",
1016
+ "BFD_RELOC_MSP430X_DST",
1017
+ "BFD_RELOC_MSP430X_DST_2ND_BYTE",
1018
+ "BFD_RELOC_MSP430X_DST_2ND",
1019
+ "BFD_RELOC_MSP430X_PCREL_SRC_BYTE",
1020
+ "BFD_RELOC_MSP430X_PCREL_SRC",
1021
+ "BFD_RELOC_MSP430X_PCREL_DST_BYTE",
1022
+ "BFD_RELOC_MSP430X_PCREL_DST",
1023
+ "BFD_RELOC_MSP430X_PCREL_DST_2ND",
1024
+ "BFD_RELOC_MSP430X_PCREL_DST_2ND_BYTE",
1025
+ "BFD_RELOC_MSP430X_S_BYTE",
1026
+ "BFD_RELOC_MSP430X_S",
1027
+ "BFD_RELOC_MSP430X_D_BYTE",
1028
+ "BFD_RELOC_MSP430X_D",
1029
+ "BFD_RELOC_MSP430X_PCREL_D",
1030
+ "BFD_RELOC_MSP430X_INDXD",
1031
+ "BFD_RELOC_MSP430X_PCREL_INDXD",
1032
"BFD_RELOC_IQ2000_OFFSET_16",
1033
"BFD_RELOC_IQ2000_OFFSET_21",
1034
"BFD_RELOC_IQ2000_UHI16",
1035
diff --git a/bfd/reloc.c b/bfd/reloc.c
1036
index 202a340..7b60036 100644
1039
@@ -5247,6 +5247,44 @@ ENUMX
1040
BFD_RELOC_MSP430_2X_PCREL
1042
BFD_RELOC_MSP430_RL_PCREL
1044
+ BFD_RELOC_MSP430X_SRC_BYTE
1046
+ BFD_RELOC_MSP430X_SRC
1048
+ BFD_RELOC_MSP430X_DST_BYTE
1050
+ BFD_RELOC_MSP430X_DST
1052
+ BFD_RELOC_MSP430X_DST_2ND_BYTE
1054
+ BFD_RELOC_MSP430X_DST_2ND
1056
+ BFD_RELOC_MSP430X_PCREL_SRC_BYTE
1058
+ BFD_RELOC_MSP430X_PCREL_SRC
1060
+ BFD_RELOC_MSP430X_PCREL_DST_BYTE
1062
+ BFD_RELOC_MSP430X_PCREL_DST
1064
+ BFD_RELOC_MSP430X_PCREL_DST_2ND
1066
+ BFD_RELOC_MSP430X_PCREL_DST_2ND_BYTE
1068
+ BFD_RELOC_MSP430X_S_BYTE
1070
+ BFD_RELOC_MSP430X_S
1072
+ BFD_RELOC_MSP430X_D_BYTE
1074
+ BFD_RELOC_MSP430X_D
1076
+ BFD_RELOC_MSP430X_PCREL_D
1078
+ BFD_RELOC_MSP430X_INDXD
1080
+ BFD_RELOC_MSP430X_PCREL_INDXD
1082
msp430 specific relocation codes
1084
diff --git a/gas/config/tc-msp430.c b/gas/config/tc-msp430.c
1085
index 98d90c6..583af27 100644
1086
--- a/gas/config/tc-msp430.c
1087
+++ b/gas/config/tc-msp430.c
1092
-#define PUSH_1X_WORKAROUND
1094
#include "subsegs.h"
1095
#include "opcode/msp430.h"
1098
int msp430_enable_relax;
1099
int msp430_enable_polys;
1100
+int msp430x_repeats; // It's not a right way to use global variable, but I don't know other way how to do it
1102
/* GCC uses the some condition codes which we'll
1103
implement as new polymorph instructions.
1104
@@ -99,12 +99,13 @@ int msp430_enable_polys;
1105
Also, we add 'jump' instruction:
1106
jump UNCOND -> jmp br lab
1108
- They will have fmt == 4, and insn_opnumb == number of instruction. */
1109
+ They will have opcode_format() == FMT_EMULATED_POLYMORPH_JUMP,
1110
+ and opcode_variant() == number of instruction. */
1115
- int index; /* Corresponding insn_opnumb. */
1116
+ int index; /* Corresponding opcode_variant(). */
1117
int sop; /* Opcode if jump length is short. */
1118
long lpos; /* Label position. */
1119
long lop0; /* Opcode 1 _word_ (16 bits). */
1120
@@ -143,7 +144,7 @@ static struct rcodes_s msp430_rcodes[] =
1124
- int index; /* Corresponding insn_opnumb. */
1125
+ int index; /* Corresponding opcode_variant(). */
1126
int tlab; /* Number of labels in short mode. */
1127
int op0; /* Opcode for first word of short jump. */
1128
int op1; /* Opcode for second word of short jump. */
1129
@@ -228,116 +229,373 @@ relax_typeS md_relax_table[] =
1133
-#define MAX_OP_LEN 256
1136
+/** List known silicon errata with a description of the problem (where
1137
+ * this can be found). Errata descriptions are available in PDF files
1138
+ * that can be found on the device-specific web page at TI. Errata
1139
+ * numbers are consistent across the product line.
1141
+ * Note that not all documented errata are currently recognized by the
1142
+ * assembler. In fact, most are completely ignored. Future work...
1144
+ * Legacy errata descriptions are from previous versions of
1146
+typedef enum msp430_errata_e
1153
-#define MSP430_ISA_11 11
1154
-#define MSP430_ISA_110 110
1155
-#define MSP430_ISA_12 12
1156
-#define MSP430_ISA_13 13
1157
-#define MSP430_ISA_14 14
1158
-#define MSP430_ISA_15 15
1159
-#define MSP430_ISA_16 16
1160
-#define MSP430_ISA_21 21
1161
-#define MSP430_ISA_31 31
1162
-#define MSP430_ISA_32 32
1163
-#define MSP430_ISA_33 33
1164
-#define MSP430_ISA_41 41
1165
-#define MSP430_ISA_42 42
1166
-#define MSP430_ISA_43 43
1167
-#define MSP430_ISA_44 44
1169
-#define CHECK_RELOC_MSP430 ((imm_op || byte_op)?BFD_RELOC_MSP430_16_BYTE:BFD_RELOC_MSP430_16)
1170
-#define CHECK_RELOC_MSP430_PCREL ((imm_op || byte_op)?BFD_RELOC_MSP430_16_PCREL_BYTE:BFD_RELOC_MSP430_16_PCREL)
1172
-static struct mcu_type_s mcu_types[] =
1174
- {"msp1", MSP430_ISA_11, bfd_mach_msp11},
1175
- {"msp2", MSP430_ISA_14, bfd_mach_msp14},
1176
- {"msp430x110", MSP430_ISA_11, bfd_mach_msp11},
1177
- {"msp430x112", MSP430_ISA_11, bfd_mach_msp11},
1178
- {"msp430x1101", MSP430_ISA_110, bfd_mach_msp110},
1179
- {"msp430x1111", MSP430_ISA_110, bfd_mach_msp110},
1180
- {"msp430x1121", MSP430_ISA_110, bfd_mach_msp110},
1181
- {"msp430x1122", MSP430_ISA_11, bfd_mach_msp110},
1182
- {"msp430x1132", MSP430_ISA_11, bfd_mach_msp110},
1184
- {"msp430x122", MSP430_ISA_12, bfd_mach_msp12},
1185
- {"msp430x123", MSP430_ISA_12, bfd_mach_msp12},
1186
- {"msp430x1222", MSP430_ISA_12, bfd_mach_msp12},
1187
- {"msp430x1232", MSP430_ISA_12, bfd_mach_msp12},
1189
- {"msp430x133", MSP430_ISA_13, bfd_mach_msp13},
1190
- {"msp430x135", MSP430_ISA_13, bfd_mach_msp13},
1191
- {"msp430x1331", MSP430_ISA_13, bfd_mach_msp13},
1192
- {"msp430x1351", MSP430_ISA_13, bfd_mach_msp13},
1193
- {"msp430x147", MSP430_ISA_14, bfd_mach_msp14},
1194
- {"msp430x148", MSP430_ISA_14, bfd_mach_msp14},
1195
- {"msp430x149", MSP430_ISA_14, bfd_mach_msp14},
1197
- {"msp430x155", MSP430_ISA_15, bfd_mach_msp15},
1198
- {"msp430x156", MSP430_ISA_15, bfd_mach_msp15},
1199
- {"msp430x157", MSP430_ISA_15, bfd_mach_msp15},
1200
- {"msp430x167", MSP430_ISA_16, bfd_mach_msp16},
1201
- {"msp430x168", MSP430_ISA_16, bfd_mach_msp16},
1202
- {"msp430x169", MSP430_ISA_16, bfd_mach_msp16},
1203
- {"msp430x1610", MSP430_ISA_16, bfd_mach_msp16},
1204
- {"msp430x1611", MSP430_ISA_16, bfd_mach_msp16},
1205
- {"msp430x1612", MSP430_ISA_16, bfd_mach_msp16},
1207
- {"msp430x2101", MSP430_ISA_21, bfd_mach_msp21},
1208
- {"msp430x2111", MSP430_ISA_21, bfd_mach_msp21},
1209
- {"msp430x2121", MSP430_ISA_21, bfd_mach_msp21},
1210
- {"msp430x2131", MSP430_ISA_21, bfd_mach_msp21},
1211
+ /* CPU4: PUSH #4, PUSH #8
1213
+ * The single operand instruction PUSH cannot use the internal
1214
+ * constants (CG) 4 and 8. The other internal constants (0, 1, 2,
1215
+ * –1) can be used. The number of clock cycles is different:
1217
+ * - PUSH #CG uses address mode 00, requiring 3 cycles, 1-word instruction
1218
+ * - PUSH #4/#8 uses address mode 11, requiring 5 cycles, 2-word instruction
1221
+ * - Assembler generate code not referencing constant generator
1225
+ // CALL and PUSH with @SP+, @SP, and X(SP) uses the SP to calculate the address, then decrements it
1228
+ /* CPU8: Using odd values in the SP register
1230
+ * The SP can be written with odd values. In the original CPU, an
1231
+ * odd SP value could be combined with an odd offset (for example,
1232
+ * mov. #value, 5(SP)). In the new CPU, the SP can be written with
1233
+ * an odd value, but the first time the SP is used, the LSB is
1237
+ * - Do not use odd values with the SP.
1239
+ ERRATUM_CPU8 = 8, /* UNHANDLED */
1241
+ /* CPU11: Invalid status register after program counter access
1243
+ * When addressing the program counter (PC) in register mode when
1244
+ * the PC is the destination, the Status Register (SR) may be
1245
+ * erroneous. The instructions BIS, BIC, and MOV do not affect SR
1246
+ * contents. Only CPU flags are affected. This bug does not apply to
1247
+ * LPMx control bits.
1249
+ * Workaround: None
1251
+ ERRATUM_CPU11 = 11, /* UNHANDLED */
1253
+ /* CPU12: CMP or BIT with PC destination
1255
+ * Any instruction immediately following a CMP(.B) or BIT(.B)
1256
+ * instruction when the PC is the destination address using register
1257
+ * mode is ignored or erroneously executed. When the following
1258
+ * instruction is longer than one word, the second word is fetched
1259
+ * by the CPU and decoded as the instruction, leading to
1260
+ * unpredictable behavior. Affected source-addressing modes are
1261
+ * indexed and indirect addressing modes.
1266
+ * The add command is not executed.
1269
+ * - Insert a NOP instruction after the BIT or CMP instruction. The
1270
+ * NOP is ignored, and program execution continues as expected.
1272
+ ERRATUM_CPU12 = 12, /* UNHANDLED */
1274
+ /* CPU13: Arithmetic operations and the SR
1276
+ * Performing arithmetic operations with the Status Register (SR) as
1277
+ * the destination address does not update the SR as intended. The
1278
+ * result in SR can be invalid, leading to erroneous low-power mode
1279
+ * entry. Arithmetic operations are defined as all instructions that
1280
+ * modify the SR flag bits (RRA, SUB, XOR, and ADD, for example).
1282
+ * Workaround: None
1284
+ ERRATUM_CPU13 = 13, /* UNHANDLED */
1286
+ /* CPU15: Modifying the Program Counter (PC) behaves differently
1287
+ * than in previous devices
1289
+ * When using instructions with immediate or indirect addressing
1290
+ * mode to modify the PC, a different value compared to previous
1291
+ * devices must be added to get to the same destination.
1293
+ * NOTE: The MOV instruction is not affected
1295
+ * Example: Previous device (MSP430F4619)
1296
+ * label_1 ADD.W #Branch1-label_1-4h,PC
1298
+ * label_1 ADD.W #Branch1-label_1-2h,PC
1301
+ * - Additional NOP after the PC-modifying instruction; or
1302
+ * - Change the offset value in software
1304
+ ERRATUM_CPU15 = 15, /* UNHANDLED */
1306
+ /* CPU16 Indexed addressing with instructions calla, mova, and bra
1308
+ * With indexed addressing mode and instructions calla, mova, and bra, it is not possible
1309
+ * to reach memory above 64k if the register content is < 64k.
1310
+ * Example: Assume R5 = FFFEh. The instruction calla 0004h(R5) results in a 20-bit call
1311
+ * of address 0002h instead of 10002h.
1314
+ * - Use different addressing mode to reach memory above 64k.
1315
+ * - First use adda [index],[Rx] to calculate address in upper memory and then use
1318
+ ERRATUM_CPU16 = 16, /* UNHANDLED */
1320
+ /* CPU18: LPM instruction can corrupt PC/SR registers
1322
+ * The PC and SR registers have the potential to be corrupted when:
1323
+ * - An instruction using register, absolute, indexed, indirect,
1324
+ * indirect auto-increment, or symbolic mode is used to set the
1325
+ * LPM bits (for example, BIS &xyh, SR).
1327
+ * - This instruction is followed by a CALL or CALLA instruction.
1329
+ * Upon servicing an interrupt service routine, the program counter
1330
+ * (PC) is pushed twice onto the stack instead of the correct
1331
+ * operation where the PC, then the SR registers are pushed onto the
1332
+ * stack. This corrupts the SR and possibly the PC on RETI from the
1336
+ * - Insert a NOP or __no_operation() intrinsic function between the
1337
+ * instruction to enter low-power mode and the CALL or CALLA
1340
+ ERRATUM_CPU18 = 18, /* UNHANDLED */
1342
+ /* CPU19: CPUOFF can change register values
1344
+ * If a CPUOFF command is followed by an instruction with an
1345
+ * indirect addressed operand (for example, mov @R8, R9, and RET),
1346
+ * an unintentional register-read operation can occur during the
1347
+ * wakeup of the CPU. If the unintentional read occurs to a
1348
+ * read-sensitive register (for example, UCB0RXBUF or TAIV), which
1349
+ * changes its value or the value of other registers (IFGs), the bug
1350
+ * leads to lost interrupts or wrong register read values.
1353
+ * - Insert a NOP instruction after each CPUOFF instruction.
1355
+ ERRATUM_CPU19 = 19, /* UNHANDLED */
1357
+ /* CPU20: An unexpected Vacant Memory Access Flag (VMAIFG) can be
1358
+ * triggered due to the CPU autoincrement of the MAB + 2
1359
+ * outside the range of a valid memory block.
1361
+ * The VMAIFG is triggered if a PC-modifying instruction (for
1362
+ * example, ret, push, call, pop, jmp, br) is fetched from the last
1363
+ * address of a section of memory (for example, flash or RAM) that
1364
+ * is not contiguous to a higher valid section on the memory map.
1367
+ * - If code is affected, edit the linker command file to make the
1368
+ * last four bytes of affected memory sections unavailable.
1370
+ ERRATUM_CPU20 = 20, /* UNHANDLED */
1372
+ /* NO DESCRIPTION */
1373
+ ERRATUM_CPU21 = 21, /* UNHANDLED */
1375
+ /* NO DESCRIPTION */
1376
+ ERRATUM_CPU22 = 22, /* UNHANDLED */
1378
+ /* NO DESCRIPTION */
1379
+ ERRATUM_CPU23 = 23, /* UNHANDLED */
1381
+ /* CPU26: CALL SP does not behave as expected
1383
+ * When the intention is to execute code from the stack, a CALL SP
1384
+ * instruction skips the first piece of data (instruction) on the
1385
+ * stack. The second piece of data at SP + 2 is used as the first
1386
+ * executable instruction.
1389
+ * - Write the op code for a NOP as the first instruction on the
1390
+ * stack. Begin the intended subroutine at address SP + 2.
1392
+ ERRATUM_CPU26 = 26, /* UNHANDLED */
1394
+ /* CPU27: Program Counter (PC) is corrupted during the context save
1395
+ * of a nested interrupt
1397
+ * When a low-power mode is entered within an interrupt service
1398
+ * routine that has enabled nested interrupts (by setting the GIE
1399
+ * bit), and the instruction that sets the low-power mode is
1400
+ * directly followed by a RETI instruction, an incorrect value of PC
1401
+ * + 2 is pushed to the stack during the context save. Hence, the
1402
+ * RETI instruction is not executed on return from the nested
1403
+ * interrupt, and the PC becomes corrupted.
1406
+ * - Insert a NOP or __no_operation() intrinsic function between the
1407
+ * instruction that sets the lower power mode and the RETI
1410
+ ERRATUM_CPU27 = 27, /* UNHANDLED */
1412
+ /* CPU28: PC is corrupted when using certain extended addressing
1413
+ * mode combinations
1415
+ * An extended memory instruction that modifies the program counter
1416
+ * executes incorrectly when preceded by an extended memory
1417
+ * write-back instruction under the following conditions:
1419
+ * - First instruction:
1420
+ * 2-operand instruction, extended mode using (register,index),
1421
+ * (register,absolute), or (register,symbolic) addressing modes
1422
+ * - Second instruction:
1423
+ * 2-operand instruction, extended mode using the (indirect,PC),
1424
+ * (indirect auto-increment,PC), or (indexed [with ind 0], PC)
1425
+ * addressing modes
1428
+ * BISX.A R6,&AABCD
1432
+ * - Insert a NOP or a __no_operation() intrinsic function between
1433
+ * the two instructions.
1435
+ * - Do not use an extended memory instruction to modify the PC.
1437
+ ERRATUM_CPU28 = 28, /* UNHANDLED */
1439
+ /* CPU29: Using a certain instruction sequence to enter low-power
1440
+ * mode(s) affects the instruction width of the first
1441
+ * instruction in an NMI ISR
1443
+ * If there is a pending NMI request when the CPU enters a low-power
1444
+ * mode (LPMx) using an instruction of Indexed source addressing
1445
+ * mode, and that instruction is followed by a 20-bit wide
1446
+ * instruction of Register source and Destination addressing modes,
1447
+ * the first instruction of the ISR is executed as a 20-bit wide
1453
+ * MOV.W [indexed],SR ; Enter LPMx
1454
+ * MOVX.A [register],[register] ; 20-bit wide instruction
1457
+ * MOV.B [indexed],[register] ; ERROR - Executed as a 20-bit instruction!
1459
+ * Note: [ ] indicates addressing mode
1462
+ * - Insert a NOP or a __no_operation() intrinsic function following
1463
+ * the instruction that enters the LPMx using indexed addressing
1466
+ * - Use a NOP or a __no_operation() intrinsic function as first
1467
+ * instruction in the ISR.
1469
+ * - Do not use the indexed mode to enter LPMx.
1471
+ ERRATUM_CPU29 = 29, /* UNHANDLED */
1473
- {"msp430x311", MSP430_ISA_31, bfd_mach_msp31},
1474
- {"msp430x312", MSP430_ISA_31, bfd_mach_msp31},
1475
- {"msp430x313", MSP430_ISA_31, bfd_mach_msp31},
1476
- {"msp430x314", MSP430_ISA_31, bfd_mach_msp31},
1477
- {"msp430x315", MSP430_ISA_31, bfd_mach_msp31},
1478
- {"msp430x323", MSP430_ISA_32, bfd_mach_msp32},
1479
- {"msp430x325", MSP430_ISA_32, bfd_mach_msp32},
1480
- {"msp430x336", MSP430_ISA_33, bfd_mach_msp33},
1481
- {"msp430x337", MSP430_ISA_33, bfd_mach_msp33},
1483
- {"msp430x412", MSP430_ISA_41, bfd_mach_msp41},
1484
- {"msp430x413", MSP430_ISA_41, bfd_mach_msp41},
1485
- {"msp430x415", MSP430_ISA_41, bfd_mach_msp41},
1486
- {"msp430x417", MSP430_ISA_41, bfd_mach_msp41},
1488
- {"msp430xE423", MSP430_ISA_42, bfd_mach_msp42},
1489
- {"msp430xE425", MSP430_ISA_42, bfd_mach_msp42},
1490
- {"msp430xE427", MSP430_ISA_42, bfd_mach_msp42},
1492
- {"msp430xW423", MSP430_ISA_42, bfd_mach_msp42},
1493
- {"msp430xW425", MSP430_ISA_42, bfd_mach_msp42},
1494
- {"msp430xW427", MSP430_ISA_42, bfd_mach_msp42},
1496
- {"msp430xG437", MSP430_ISA_43, bfd_mach_msp43},
1497
- {"msp430xG438", MSP430_ISA_43, bfd_mach_msp43},
1498
- {"msp430xG439", MSP430_ISA_43, bfd_mach_msp43},
1500
- {"msp430x435", MSP430_ISA_43, bfd_mach_msp43},
1501
- {"msp430x436", MSP430_ISA_43, bfd_mach_msp43},
1502
- {"msp430x437", MSP430_ISA_43, bfd_mach_msp43},
1503
- {"msp430x447", MSP430_ISA_44, bfd_mach_msp44},
1504
- {"msp430x448", MSP430_ISA_44, bfd_mach_msp44},
1505
- {"msp430x449", MSP430_ISA_44, bfd_mach_msp44},
1508
+ /* CPU30: ADDA, SUBA, CMPA [immediate],PC behave as if immediate
1509
+ * value were offset by -2
1511
+ * The extended address instructions ADDA, SUBA, and CMPA in
1512
+ * immediate addressing mode are represented by 4 bytes of opcode
1513
+ * (see the MSP430F5xx Family User's Guide (SLAU208) for more
1514
+ * details). In cases where the program counter (PC) is used as the
1515
+ * destination register, only 2 bytes of the current instruction's
1516
+ * 4-byte opcode are accounted for in the PC value. The resulting
1517
+ * operation executes as if the immediate value were offset by a
1521
+ * Ideal: ADDA #Immediate-4, PC
1522
+ * ...is equivalent to...
1523
+ * Actual: ADDA #Immediate-2, PC
1524
+ * NOTE: The MOV instruction is not affected.
1527
+ * - Modify immediate value in software to account for the offset of 2.
1529
+ * - Use extended 20-bit instructions (addx.a, subx.a, cmpx.a) instead.
1531
+ ERRATUM_CPU30 = 30, /* UNHANDLED */
1533
+ /* CPU40: PC is corrupted when executing jump/conditional jump
1534
+ * instruction that is followed by instruction with PC as
1535
+ * destination register or a data section
1537
+ * If the value at the memory location immediately following a
1538
+ * jump/conditional jump instruction is 0X40h or 0X50h (where X =
1539
+ * don't care), which could either be an instruction opcode (for
1540
+ * instructions like RRCM, RRAM, RLAM, RRUM) with PC as destination
1541
+ * register or a data section (const data in flash memory or data
1542
+ * variable in RAM), then the PC value gets auto-incremented by 2
1543
+ * after the jump instruction is executed; thus branching to a wrong
1544
+ * address location in code and leading to wrong program execution.
1546
+ * For example, a conditional jump instruction followed by data
1547
+ * section (0140h).
1549
+ * @0x8012 Loop DEC.W R6
1550
+ * @0x8014 DEC.W R7
1551
+ * @0x8016 JNZ Loop
1552
+ * @0x8018 Value1 DW 0140h
1555
+ * - In assembly, insert a NOP between the jump/conditional jump
1556
+ * instruction and program code with instruction that contains PC
1557
+ * as destination register or the data section.
1559
+ ERRATUM_CPU40 = 40, /* UNHANDLED */
1562
+/* sed -e '1,/enum msp430_errata/d' -e '/^\}/,$d' tc-msp430.c \
1563
+ | grep '^ *ERRATUM_*' \
1565
+ | sed 's@ *$@,@' */
1566
+static const int recognized_errata[] = {
1589
+#define CHECK_RELOC_MSP430 ((imm_op || op_width == BYTE_OP) ? BFD_RELOC_MSP430_16_BYTE : BFD_RELOC_MSP430_16)
1590
+#define CHECK_RELOC_MSP430_PCREL ((imm_op || op_width == BYTE_OP) ? BFD_RELOC_MSP430_16_PCREL_BYTE : BFD_RELOC_MSP430_16_PCREL)
1591
+#define CHECK_RELOC_MSP430X_SRC ((imm_op || op_width == BYTE_OP) ? BFD_RELOC_MSP430X_SRC_BYTE : BFD_RELOC_MSP430X_SRC)
1592
+#define CHECK_RELOC_MSP430X_PCREL_SRC ((imm_op || op_width == BYTE_OP) ? BFD_RELOC_MSP430X_PCREL_SRC_BYTE : BFD_RELOC_MSP430X_PCREL_SRC)
1593
+#define CHECK_RELOC_MSP430X_DST ((imm_op || op_width == BYTE_OP) ? BFD_RELOC_MSP430X_DST_BYTE : BFD_RELOC_MSP430X_DST)
1594
+#define CHECK_RELOC_MSP430X_PCREL_DST ((imm_op || op_width == BYTE_OP) ? BFD_RELOC_MSP430X_PCREL_DST_BYTE : BFD_RELOC_MSP430X_PCREL_DST)
1595
+#define CHECK_RELOC_MSP430X_DST_2ND ((imm_op || op_width == BYTE_OP) ? BFD_RELOC_MSP430X_DST_2ND_BYTE : BFD_RELOC_MSP430X_DST_2ND)
1596
+#define CHECK_RELOC_MSP430X_PCREL_DST_2ND ((imm_op || op_width == BYTE_OP) ? BFD_RELOC_MSP430X_PCREL_DST_2ND_BYTE : BFD_RELOC_MSP430X_PCREL_DST_2ND)
1598
-static struct mcu_type_s default_mcu =
1599
- { "msp430x11", MSP430_ISA_11, bfd_mach_msp11 };
1601
-static struct mcu_type_s * msp430_mcu = & default_mcu;
1602
+static int msp430_cpu = MSP430_CPU_MSP430;
1603
+static int msp430_mpy = MSP430_MPY_NONE;
1604
+static int *msp430_errata = 0;
1606
/* Profiling capability:
1607
It is a performance hit to use gcc's profiling approach for this tiny target.
1608
@@ -446,32 +704,14 @@ pow2value (int y)
1610
parse_exp (char * s, expressionS * op)
1612
+ char * in_save = input_line_pointer;
1613
input_line_pointer = s;
1615
+ s = input_line_pointer;
1616
+ input_line_pointer = in_save;
1617
if (op->X_op == O_absent)
1618
as_bad (_("missing operand"));
1619
- return input_line_pointer;
1623
-/* Delete spaces from s: X ( r 1 2) => X(r12). */
1626
-del_spaces (char * s)
1634
- while (ISSPACE (*m) && *m)
1636
- memmove (s, m, strlen (m) + 1);
1644
static inline char *
1645
@@ -482,42 +722,46 @@ skip_space (char * s)
1649
-/* Extract one word from FROM and copy it to TO. Delimiters are ",;\n" */
1651
+/* Extract one word from the input. Delimiters are ",;\n" */
1653
-extract_operand (char * from, char * to, int limit)
1658
- /* Drop leading whitespace. */
1659
- from = skip_space (from);
1660
+ char* sp = input_line_pointer;
1664
+ int operand_length = 0;
1666
- while (size < limit && *from)
1667
+ while (sp && ',' != *sp && ';' != *sp && '\n' != *sp)
1669
- *(to + size) = *from;
1670
- if (*from == ',' || *from == ';' || *from == '\n')
1674
+ if (! ISSPACE(*sp))
1686
+ if (',' == *end_ilp)
1689
+ dp = dest = xmalloc(operand_length + 1);
1690
+ sp = input_line_pointer;
1691
+ while (0 < operand_length) {
1692
+ if (! ISSPACE(*sp)) {
1699
+ input_line_pointer = end_ilp;
1704
msp430_profiler (int dummy ATTRIBUTE_UNUSED)
1706
- char buffer[1024];
1708
- char * str = buffer;
1710
+ char * flag_token = 0;
1717
@@ -549,8 +793,7 @@ msp430_profiler (int dummy ATTRIBUTE_UNUSED)
1721
- input_line_pointer = extract_operand (input_line_pointer, flags, 32);
1723
+ flags = flag_token = get_operand ();
1727
@@ -608,6 +851,7 @@ msp430_profiler (int dummy ATTRIBUTE_UNUSED)
1731
+ xfree (flag_token);
1734
&& ( ! pow2value (p_flags & ( MSP430_PROFILER_FLAG_ENTRY
1735
@@ -658,11 +902,11 @@ msp430_profiler (int dummy ATTRIBUTE_UNUSED)
1738
/* Now get profiling info. */
1739
- halt = extract_operand (input_line_pointer, str, 1024);
1740
+ char *halt = get_operand ();
1741
/* Process like ".word xxx" directive. */
1742
- parse_exp (str, & exp);
1743
+ parse_exp (halt, & exp);
1744
emit_expr (& exp, 2);
1745
- input_line_pointer = halt;
1749
/* Fill the rest with zeros. */
1750
@@ -675,79 +919,178 @@ msp430_profiler (int dummy ATTRIBUTE_UNUSED)
1751
subseg_set (seg, subseg);
1755
-extract_word (char * from, char * to, int limit)
1756
+struct tag_value_pair_t
1761
+ unsigned long value;
1764
- /* Drop leading whitespace. */
1765
- from = skip_space (from);
1767
+static const struct tag_value_pair_t cpu_tag_value_map[] = {
1768
+ {"430", MSP430_CPU_MSP430},
1769
+ {"430x", MSP430_CPU_MSP430X},
1770
+ {"430xv2", MSP430_CPU_MSP430XV2},
1774
+static const struct tag_value_pair_t mpy_tag_value_map[] = {
1775
+ {"none", MSP430_MPY_NONE},
1776
+ {"16", MSP430_MPY_16},
1777
+ {"16se", MSP430_MPY_16SE},
1778
+ {"32", MSP430_MPY_32},
1779
+ {"32dw", MSP430_MPY_32DW},
1783
- /* Find the op code end. */
1784
- for (op_end = from; *op_end != 0 && is_part_of_name (*op_end);)
1785
+static const struct tag_value_pair_t *
1786
+find_pair_by_tag (const char *tag, const struct tag_value_pair_t *map)
1790
- to[size++] = *op_end++;
1791
- if (size + 1 >= limit)
1793
+ if (0 == strcmp (tag, map->tag))
1803
+static const struct tag_value_pair_t *
1804
+find_pair_by_value (unsigned long value, const struct tag_value_pair_t *map)
1808
+ if (map->value == value)
1816
-#define OPTION_MMCU 'm'
1817
-#define OPTION_RELAX 'Q'
1818
-#define OPTION_POLYMORPHS 'P'
1820
+ OPTION_MMCU = 'm',
1821
+ OPTION_RELAX = 'Q',
1822
+ OPTION_POLYMORPHS = 'P',
1823
+ OPTION_CPU = OPTION_MD_BASE + 0,
1829
+erratum_applies (int erratum)
1831
+ if (! msp430_errata)
1832
+ if (ERRATUM_CPU4 == erratum)
1833
+ return msp430_cpu < MSP430_CPU_MSP430X;
1838
+cpu_from_text (const char* text)
1840
+ const struct tag_value_pair_t* mp = find_pair_by_tag(text, cpu_tag_value_map);
1842
+ as_fatal (_("unrecognized cpu type %s"), text);
1847
+mpy_from_text (const char* text)
1849
+ const struct tag_value_pair_t* mp = find_pair_by_tag(text, mpy_tag_value_map);
1851
+ as_fatal (_("unrecognized hardware multiplier type %s"), text);
1856
-msp430_set_arch (int dummy ATTRIBUTE_UNUSED)
1857
+set_arch_mach (int cpu,
1858
+ int mpy ATTRIBUTE_UNUSED)
1860
- char *str = (char *) alloca (32); /* 32 for good measure. */
1861
+ unsigned long mach = bfd_mach_msp430;
1862
+ if (MSP430_CPU_MSP430X <= cpu)
1863
+ mach = bfd_mach_msp430x;
1864
+ bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
1867
- input_line_pointer = extract_word (input_line_pointer, str, 32);
1868
+/* Like get_symbol_end, but accepts sequences that start with
1869
+ * digits and doesn't strip out name ends */
1871
+get_token_end (void)
1875
- md_parse_option (OPTION_MMCU, str);
1876
- bfd_set_arch_mach (stdoutput, TARGET_ARCH, msp430_mcu->mach);
1877
+ while (is_part_of_name (c = *input_line_pointer++))
1879
+ *--input_line_pointer = 0;
1884
-show_mcu_list (FILE * stream)
1885
+msp430_set_mcu (int dummy ATTRIBUTE_UNUSED)
1888
+ SKIP_WHITESPACE();
1889
+ if (!is_end_of_line[(unsigned char) *input_line_pointer])
1891
+ char* tag_start = input_line_pointer;
1892
+ int ch = get_token_end ();
1893
+ md_parse_option (OPTION_MMCU, tag_start);
1894
+ *input_line_pointer = ch;
1895
+ demand_empty_rest_of_line ();
1898
+ as_bad (_("missing value for arch"));
1902
+msp430_set (int option)
1906
+ SKIP_WHITESPACE ();
1907
+ if (!is_end_of_line[(unsigned char) *input_line_pointer])
1909
+ char *tag_start = input_line_pointer;
1910
+ char e = get_token_end ();
1911
+ int tag_len = input_line_pointer + 1 - tag_start;
1912
+ tag = (char *) xmalloc(tag_len);
1913
+ memcpy (tag, tag_start, tag_len);
1914
+ *input_line_pointer = e;
1915
+ demand_empty_rest_of_line ();
1922
+ as_bad (_("missing value for cpu"));
1923
+ msp430_cpu = cpu_from_text(tag);
1927
+ as_bad (_("missing value for mpy"));
1928
+ msp430_mpy = mpy_from_text(tag);
1934
- fprintf (stream, _("Known MCU names:\n"));
1935
+ set_arch_mach (msp430_cpu, msp430_mpy);
1937
- for (i = 0; mcu_types[i].name; i++)
1938
- fprintf (stream, _("\t %s\n"), mcu_types[i].name);
1941
- fprintf (stream, "\n");
1943
+msp430_set_errata (int dummy ATTRIBUTE_UNUSED)
1948
md_parse_option (int c, char * arg)
1955
- for (i = 0; mcu_types[i].name; ++i)
1956
- if (strcmp (mcu_types[i].name, arg) == 0)
1959
- if (!mcu_types[i].name)
1961
- show_mcu_list (stderr);
1962
- as_fatal (_("unknown MCU: %s\n"), arg);
1965
- if (msp430_mcu == &default_mcu || msp430_mcu->mach == mcu_types[i].mach)
1966
- msp430_mcu = &mcu_types[i];
1968
- as_fatal (_("redefinition of mcu type %s' to %s'"),
1969
- msp430_mcu->name, mcu_types[i].name);
1970
+ //as_tsktsk(_("mcu option ignored"));
1974
@@ -760,16 +1103,35 @@ md_parse_option (int c, char * arg)
1975
msp430_enable_polys = 1;
1980
+ msp430_cpu = cpu_from_text(arg);
1985
+ msp430_mpy = mpy_from_text(arg);
1989
+ case OPTION_ERRATA:
1997
+msp430_repeat_insn (int dummy ATTRIBUTE_UNUSED);
1999
const pseudo_typeS md_pseudo_table[] =
2001
- {"arch", msp430_set_arch, 0},
2002
+ {"arch", msp430_set_mcu, 0},
2003
{"profiler", msp430_profiler, 0},
2004
+ {"rpt", msp430_repeat_insn, 0},
2005
+ {"cpu", msp430_set, OPTION_CPU},
2006
+ {"mpy", msp430_set, OPTION_MPY},
2007
+ {"errata", msp430_set_errata, 0},
2011
@@ -780,6 +1142,9 @@ struct option md_longopts[] =
2012
{"mmcu", required_argument, NULL, OPTION_MMCU},
2013
{"mP", no_argument, NULL, OPTION_POLYMORPHS},
2014
{"mQ", no_argument, NULL, OPTION_RELAX},
2015
+ {"mcpu", required_argument, NULL, OPTION_CPU },
2016
+ {"mmpy", required_argument, NULL, OPTION_MPY },
2017
+ {"merrata", required_argument, NULL, OPTION_ERRATA },
2018
{NULL, no_argument, NULL, 0}
2021
@@ -789,33 +1154,13 @@ void
2022
md_show_usage (FILE * stream)
2025
- _("MSP430 options:\n"
2026
- " -mmcu=[msp430-name] select microcontroller type\n"
2027
- " msp430x110 msp430x112\n"
2028
- " msp430x1101 msp430x1111\n"
2029
- " msp430x1121 msp430x1122 msp430x1132\n"
2030
- " msp430x122 msp430x123\n"
2031
- " msp430x1222 msp430x1232\n"
2032
- " msp430x133 msp430x135\n"
2033
- " msp430x1331 msp430x1351\n"
2034
- " msp430x147 msp430x148 msp430x149\n"
2035
- " msp430x155 msp430x156 msp430x157\n"
2036
- " msp430x167 msp430x168 msp430x169\n"
2037
- " msp430x1610 msp430x1611 msp430x1612\n"
2038
- " msp430x311 msp430x312 msp430x313 msp430x314 msp430x315\n"
2039
- " msp430x323 msp430x325\n"
2040
- " msp430x336 msp430x337\n"
2041
- " msp430x412 msp430x413 msp430x415 msp430x417\n"
2042
- " msp430xE423 msp430xE425 msp430E427\n"
2043
- " msp430xW423 msp430xW425 msp430W427\n"
2044
- " msp430xG437 msp430xG438 msp430G439\n"
2045
- " msp430x435 msp430x436 msp430x437\n"
2046
- " msp430x447 msp430x448 msp430x449\n"));
2048
- _(" -mQ - enable relaxation at assembly time. DANGEROUS!\n"
2049
+ _("MSP430 as-specific options:\n"
2050
+ " -mmcu=[msp430-name] select microcontroller type (ignored)\n"
2051
+ " -mcpu={430,430x,430xv2} select cpu model\n"
2052
+ " -mmpy={none,16,16se,32,32dw} select hardware multiplier type\n"
2053
+ " -merrata=[cpuX,...] list relevant errata\n"
2054
+ " -mQ - enable relaxation at assembly time. DANGEROUS!\n"
2055
" -mP - enable polymorph instructions\n"));
2057
- show_mcu_list (stream);
2061
@@ -824,23 +1169,6 @@ md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
2066
-extract_cmd (char * from, char * to, int limit)
2070
- while (*from && ! ISSPACE (*from) && *from != '.' && limit > size)
2072
- *(to + size) = *from;
2083
md_atof (int type, char * litP, int * sizeP)
2085
@@ -850,13 +1178,13 @@ md_atof (int type, char * litP, int * sizeP)
2089
- struct msp430_opcode_s * opcode;
2090
+ struct msp430_opcode_s const * opcode;
2091
msp430_hash = hash_new ();
2093
for (opcode = msp430_opcodes; opcode->name; opcode++)
2094
hash_insert (msp430_hash, opcode->name, (char *) opcode);
2096
- bfd_set_arch_mach (stdoutput, TARGET_ARCH, msp430_mcu->mach);
2097
+ set_arch_mach (msp430_cpu, msp430_mpy);
2101
@@ -880,13 +1208,74 @@ check_reg (char * t)
2106
+msp430_substitute_CG(struct msp430_operand_s * op, int workaround)
2108
+ /* Substitute register mode with a constant generator if applicable. */
2109
+ if( op->mode != OP_EXP || ( op->exp.X_op != O_constant && op->exp.X_op != O_big ))
2111
+ if( op->am != 3 || op->reg != 0 ) // not #N
2113
+ int x = (short) op->exp.X_add_number; /* Extend sign. */
2120
+ op->mode = OP_REG;
2127
+ op->mode = OP_REG;
2134
+ op->mode = OP_REG;
2141
+ op->mode = OP_REG;
2143
+ else if (x == 4 && !workaround)
2148
+ op->mode = OP_REG;
2150
+ else if (x == 8 && ! workaround)
2155
+ op->mode = OP_REG;
2160
msp430_srcoperand (struct msp430_operand_s * op,
2161
- char * l, int bin, int * imm_op)
2162
+ const char * operand_string, int * imm_op, int imm_min, int imm_max)
2168
+ if (operand_string)
2170
+ l = alloca(strlen(operand_string) + 1);
2171
+ strcpy(l, operand_string);
2175
/* Check if an immediate #VALUE. The hash sign should be only at the beginning! */
2178
@@ -943,100 +1332,27 @@ msp430_srcoperand (struct msp430_operand_s * op,
2179
parse_exp (__tl, &(op->exp));
2180
if (op->exp.X_op == O_constant)
2182
- int x = op->exp.X_add_number;
2183
+ offsetT x = op->exp.X_add_number;
2184
+ int is_negative = 0 > x;
2189
- op->exp.X_add_number = x;
2191
- else if (vshift == 1)
2194
- x = (x >> 16) & 0xffff;
2195
- op->exp.X_add_number = x;
2197
- else if (vshift > 1)
2200
- op->exp.X_add_number = -1;
2201
+ unsigned int shift_bits = vshift * 16;
2202
+ if (shift_bits < (8 * sizeof (x)))
2207
+ op->exp.X_add_number = is_negative ? -1 : 0;
2209
- op->exp.X_add_number = 0; /* Nothing left. */
2210
+ op->exp.X_add_number = x & 0xFFFF;
2211
x = op->exp.X_add_number;
2214
- if (op->exp.X_add_number > 65535 || op->exp.X_add_number < -32768)
2215
+ if (x >= imm_max || x < imm_min)
2217
- as_bad (_("value %d out of range. Use #lo() or #hi()"), x);
2218
+ as_bad (_("value %ld out of %d...%d (0x%X...0x%X) range."), (long int)x, imm_min, imm_max - 1, imm_min, imm_max - 1);
2222
- /* Now check constants. */
2223
- /* Substitute register mode with a constant generator if applicable. */
2225
- x = (short) x; /* Extend sign. */
2232
- op->mode = OP_REG;
2239
- op->mode = OP_REG;
2246
- op->mode = OP_REG;
2253
- op->mode = OP_REG;
2257
-#ifdef PUSH_1X_WORKAROUND
2258
- if (bin == 0x1200)
2260
- /* Remove warning as confusing.
2261
- as_warn (_("Hardware push bug workaround")); */
2269
- op->mode = OP_REG;
2274
-#ifdef PUSH_1X_WORKAROUND
2275
- if (bin == 0x1200)
2277
- /* Remove warning as confusing.
2278
- as_warn (_("Hardware push bug workaround")); */
2286
- op->mode = OP_REG;
2290
else if (op->exp.X_op == O_symbol)
2292
@@ -1044,12 +1360,10 @@ msp430_srcoperand (struct msp430_operand_s * op,
2294
else if (op->exp.X_op == O_big)
2299
op->exp.X_op = O_constant;
2300
op->exp.X_add_number = 0xffff & generic_bignum[vshift];
2301
- x = op->exp.X_add_number;
2305
@@ -1058,49 +1372,6 @@ msp430_srcoperand (struct msp430_operand_s * op,
2315
- op->mode = OP_REG;
2322
- op->mode = OP_REG;
2329
- op->mode = OP_REG;
2336
- op->mode = OP_REG;
2343
- op->mode = OP_REG;
2350
- op->mode = OP_REG;
2353
/* Redundant (yet) check. */
2354
else if (op->exp.X_op == O_register)
2355
@@ -1127,7 +1398,7 @@ msp430_srcoperand (struct msp430_operand_s * op,
2357
int x = op->exp.X_add_number;
2359
- if (x > 65535 || x < -32768)
2360
+ if (x >= imm_max || x < imm_min)
2362
as_bad (_("value out of range: %d"), x);
2364
@@ -1262,7 +1533,7 @@ msp430_srcoperand (struct msp430_operand_s * op,
2366
int x = op->exp.X_add_number;
2368
- if (x > 65535 || x < -32768)
2369
+ if (x > imm_max || x < imm_min)
2371
as_bad (_("value out of range: %d"), x);
2373
@@ -1338,10 +1609,10 @@ msp430_srcoperand (struct msp430_operand_s * op,
2377
-msp430_dstoperand (struct msp430_operand_s * op, char * l, int bin)
2378
+msp430_dstoperand (struct msp430_operand_s * op, const char * l, int imm_min, int imm_max)
2381
- int ret = msp430_srcoperand (op, l, bin, & dummy);
2382
+ int ret = msp430_srcoperand (op, l, & dummy, imm_min, imm_max);
2386
@@ -1373,39 +1644,139 @@ msp430_dstoperand (struct msp430_operand_s * op, char * l, int bin)
2391
+msp430_repeat_insn (int dummy ATTRIBUTE_UNUSED)
2393
+ char *operand = 0;
2394
+ struct msp430_operand_s op;
2396
+ char *line = input_line_pointer;
2398
+ if (msp430_cpu < MSP430_CPU_MSP430X)
2400
+ as_bad (_("Repeatable instructions require 430X-based mcu"));
2404
+ if (msp430x_repeats)
2405
+ as_warn (_("two consecutive .rpt pseudo-ops. Previous .rpt discarded"));
2407
+ if (!*line || *line == '\n')
2409
+ as_bad (_("rpt pseudo-op requires 1 operand"));
2413
+ memset (&op, 0, sizeof (op));
2414
+ operand = get_operand ();
2416
+ if (msp430_srcoperand(&op, operand, &imm_op, 1, 15) != 0)
2419
+ if ( !(op.mode == OP_REG && op.am == 0) // Rn
2420
+ && !(op.mode == OP_EXP && op.am == 3) // #N
2423
+ as_bad (_("rpt pseudo-op requires immediate or register operand"));
2427
+ if (op.am == 0) // rpt Rn
2428
+ msp430x_repeats = (((1 << 7) | op.reg) << 1) | 1; // last bit as .rpt flag
2430
+ msp430x_repeats = ((op.exp.X_add_number - 1) << 1) | 1; // last bit as .rpt flag
2437
/* Parse instruction operands.
2438
Return binary opcode. */
2441
-msp430_operands (struct msp430_opcode_s * opcode, char * line)
2442
+msp430_operands (struct msp430_opcode_s const * opcode, char * line)
2444
int bin = opcode->bin_opcode; /* Opcode mask. */
2446
- char l1[MAX_OP_LEN], l2[MAX_OP_LEN];
2453
struct msp430_operand_s op1, op2;
2455
static short ZEROS = 0;
2456
- int byte_op, imm_op;
2459
+ opwidth_t op_width = DEFAULT_OP;
2461
/* Opcode is the one from opcodes table
2462
line contains something like
2465
- .b @r2+, 5(R1). */
2470
/* Check if byte or word operation. */
2472
if (*line == '.' && TOLOWER (*(line + 1)) == 'b')
2474
- bin |= BYTE_OPERATION;
2476
+ op_width = BYTE_OP;
2478
+ else if (*line == '.' && TOLOWER (*(line + 1)) == 'w')
2480
+ op_width = WORD_OP;
2482
+ else if (*line == '.' && TOLOWER (*(line + 1)) == 'a')
2484
+ op_width = ADDR_OP;
2489
- /* skip .[bwBW]. */
2490
+ if ((op_width == WORD_OP && !(opcode_modifier(opcode) & MOD_W))
2491
+ || (op_width == BYTE_OP && !(opcode_modifier(opcode) & MOD_B))
2492
+ || (op_width == ADDR_OP && !(opcode_modifier(opcode) & MOD_A))
2495
+ static char* const modifier[] = { "", ".w", ".b", ".a" };
2496
+ as_bad (_("%s not allowed with %s instruction"),
2497
+ modifier[op_width], opcode->name);
2501
+ if ( opcode_format(opcode) == FMT_X_DOUBLE_OPERAND
2502
+ || opcode_format(opcode) == FMT_X_SINGLE_OPERAND
2503
+ || opcode_format(opcode) == FMT_X_EMULATED
2510
+ bin |= NON_ADDR_OPERATION;
2513
+ bin |= NON_ADDR_OPERATION;
2514
+ bin |= BYTE_OPERATION_X;
2517
+ bin |= BYTE_OPERATION_X;
2523
+ if(msp430x_repeats)
2525
+ as_bad (_("%s instruction is not repeatable"), opcode->name);
2529
+ if ( opcode_format(opcode) < FMT_X && op_width == BYTE_OP ) // 430 instructions
2531
+ bin |= BYTE_OPERATION;
2534
+ /* skip .[abwABW]. */
2535
while (! ISSPACE (*line) && *line)
2538
@@ -1416,29 +1787,29 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
2542
- memset (l1, 0, sizeof (l1));
2543
- memset (l2, 0, sizeof (l2));
2544
+ input_line_pointer = line;
2546
memset (&op1, 0, sizeof (op1));
2547
memset (&op2, 0, sizeof (op2));
2551
- switch (opcode->fmt)
2552
+ switch (opcode_format(opcode))
2554
- case 0: /* Emulated. */
2555
- switch (opcode->insn_opnumb)
2556
+ case FMT_EMULATED: /* Emulated. */
2557
+ switch (opcode_variant(opcode))
2560
- /* Set/clear bits instructions. */
2562
+ /* Set/clear SR bits instructions, ret, nop */
2564
frag = frag_more (__is);
2565
bfd_putl16 ((bfd_vma) bin, frag);
2566
dwarf2_emit_insn (__is);
2570
/* Something which works with destination operand. */
2571
- line = extract_operand (line, l1, sizeof (l1));
2572
- res = msp430_dstoperand (&op1, l1, opcode->bin_opcode);
2573
+ l1 = get_operand ();
2574
+ res = msp430_dstoperand (&op1, l1, -(1<<15), (1<<16) );
2578
@@ -1463,14 +1834,13 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
2585
/* Shift instruction. */
2586
- line = extract_operand (line, l1, sizeof (l1));
2587
- strncpy (l2, l1, sizeof (l2));
2588
- l2[sizeof (l2) - 1] = '\0';
2589
- res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
2590
- res += msp430_dstoperand (&op2, l2, opcode->bin_opcode);
2591
+ l1 = get_operand ();
2592
+ res = msp430_srcoperand (&op1, l1, &imm_op, -(1<<15), (1<<16));
2593
+ msp430_substitute_CG(&op1, 0);
2594
+ res += msp430_dstoperand (&op2, l1, -(1<<15), (1<<16));
2597
break; /* An error occurred. All warnings were done before. */
2598
@@ -1498,7 +1868,12 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
2600
if (op2.mode == OP_EXP)
2604
+ x(Rn). x can be odd in non-byte operations
2605
+ except x(R2) = x(0) = &TONI and x(PC) = TONI
2607
+ imm_op = (op2.mode == 1 && op2.reg != 2 && op2.reg != 0);
2609
bfd_putl16 ((bfd_vma) ZEROS, frag + 2 + ((__is == 3) ? 2 : 0));
2611
if (op2.reg) /* Not PC relative. */
2612
@@ -1510,16 +1885,20 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
2618
/* Branch instruction => mov dst, r0. */
2619
- line = extract_operand (line, l1, sizeof (l1));
2621
- res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
2622
+ l1 = get_operand ();
2623
+ res = msp430_srcoperand (&op1, l1, &imm_op, -(1<<15), (1<<16));
2624
+ msp430_substitute_CG(&op1, 0);
2630
+ if (op1.mode == 1 && (op1.reg == 2 || op1.reg == 0))
2632
+ x(Rn). x can be odd in non-byte operations
2633
+ except x(R2) = x(0) = &EDE and x(PC) = EDE
2637
bin |= ((op1.reg << 8) | (op1.am << 4));
2639
@@ -1544,11 +1923,12 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
2643
- case 1: /* Format 1, double operand. */
2644
- line = extract_operand (line, l1, sizeof (l1));
2645
- line = extract_operand (line, l2, sizeof (l2));
2646
- res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
2647
- res += msp430_dstoperand (&op2, l2, opcode->bin_opcode);
2648
+ case FMT_DOUBLE_OPERAND: /* Format 1, double operand. */
2649
+ l1 = get_operand ();
2650
+ l2 = get_operand ();
2651
+ res = msp430_srcoperand (&op1, l1, &imm_op, -(1<<15), (1<<16));
2652
+ msp430_substitute_CG(&op1, 0);
2653
+ res += msp430_dstoperand (&op2, l2, -(1<<15), (1<<16));
2656
break; /* Error occurred. All warnings were done before. */
2657
@@ -1576,7 +1956,12 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
2659
if (op2.mode == OP_EXP)
2663
+ x(Rn). x can be odd in non-byte operations
2664
+ except x(R2) = x(0) = &TONI and x(PC) = TONI
2666
+ imm_op = (op2.mode == 1 && op2.reg != 2 && op2.reg != 0);
2668
bfd_putl16 ((bfd_vma) ZEROS, frag + 2 + ((__is == 3) ? 2 : 0));
2670
if (op2.reg) /* Not PC relative. */
2671
@@ -1588,8 +1973,8 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
2675
- case 2: /* Single-operand mostly instr. */
2676
- if (opcode->insn_opnumb == 0)
2677
+ case FMT_SINGLE_OPERAND: /* Single-operand mostly instr. */
2678
+ if (opcode_variant(opcode) == V_RETI)
2680
/* reti instruction. */
2681
frag = frag_more (2);
2682
@@ -1598,10 +1983,11 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
2686
- line = extract_operand (line, l1, sizeof (l1));
2687
- res = msp430_srcoperand (&op1, l1, opcode->bin_opcode, &imm_op);
2688
+ l1 = get_operand ();
2689
+ res = msp430_srcoperand (&op1, l1, &imm_op, -(1<<15), (1<<16));
2691
break; /* Error in operand. */
2692
+ msp430_substitute_CG(&op1, erratum_applies(ERRATUM_CPU4) && (opcode->bin_opcode == 0x1200));
2694
bin |= op1.reg | (op1.am << 4);
2696
@@ -1623,8 +2009,8 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
2700
- case 3: /* Conditional jumps instructions. */
2701
- line = extract_operand (line, l1, sizeof (l1));
2702
+ case FMT_JUMP: /* Conditional jumps instructions. */
2703
+ l1 = get_operand ();
2704
/* l1 is a label. */
2707
@@ -1693,11 +2079,13 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
2708
else if (*l1 == '$')
2710
as_bad (_("instruction requires label sans '$'"));
2716
("instruction requires label or value in range -511:512"));
2719
dwarf2_emit_insn (2 * __is);
2721
@@ -1709,14 +2097,14 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
2725
- case 4: /* Extended jumps. */
2726
+ case FMT_EMULATED_POLYMORPH_JUMP: /* Extended jumps. */
2727
if (!msp430_enable_polys)
2729
as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
2733
- line = extract_operand (line, l1, sizeof (l1));
2734
+ l1 = get_operand ();
2738
@@ -1730,7 +2118,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
2739
if (exp.X_op == O_symbol)
2741
/* Relaxation required. */
2742
- struct rcodes_s rc = msp430_rcodes[opcode->insn_opnumb];
2743
+ struct rcodes_s rc = msp430_rcodes[opcode_variant(opcode)];
2745
/* The parameter to dwarf2_emit_insn is actually the offset to the start
2746
of the insn from the fix piece of instruction that was emitted.
2747
@@ -1751,13 +2139,13 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
2748
as_bad (_("instruction requires label"));
2751
- case 5: /* Emulated extended branches. */
2752
+ case FMT_EMULATED_LONG_POLYMORPH_JUMP: /* Emulated extended branches. */
2753
if (!msp430_enable_polys)
2755
as_bad (_("polymorphs are not enabled. Use -mP option to enable."));
2758
- line = extract_operand (line, l1, sizeof (l1));
2759
+ l1 = get_operand ();
2763
@@ -1771,7 +2159,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
2764
if (exp.X_op == O_symbol)
2766
/* Relaxation required. */
2767
- struct hcodes_s hc = msp430_hcodes[opcode->insn_opnumb];
2768
+ struct hcodes_s hc = msp430_hcodes[opcode_variant(opcode)];
2770
frag = frag_more (8);
2771
dwarf2_emit_insn (0);
2772
@@ -1790,42 +2178,716 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line)
2773
as_bad (_("instruction requires label"));
2776
+ case FMT_X_DOUBLE_OPERAND: /* Extended Format 1 ( double operand). */
2777
+ l1 = get_operand ();
2778
+ l2 = get_operand ();
2779
+ res = msp430_srcoperand (&op1, l1, &imm_op, -(1<<19), (1<<20));
2780
+ msp430_substitute_CG(&op1, 0);
2781
+ res += msp430_dstoperand (&op2, l2, -(1<<19), (1<<20));
2784
+ break; /* Error occurred. All warnings were done before. */
2786
+ if (msp430x_repeats)
2788
+ if (op1.mode != OP_REG || op2.mode != OP_REG)
2790
+ as_bad(_("Repeated instruction must have register mode operands"));
2793
+ bin |= msp430x_repeats >> 1;
2794
+ msp430x_repeats = 0;
2797
+ bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7)) << 16;
2799
+ __is = 2 + op1.ol + op2.ol; /* insn size in words, opcode is 2 words wide. */
2800
+ frag = frag_more (2 * __is);
2801
+ where = frag - frag_now->fr_literal;
2802
+ bfd_putl32 ((bfd_vma) bin, frag);
2803
+ dwarf2_emit_insn (2 * __is);
2805
+ if (op1.mode == OP_EXP)
2807
+ bfd_putl16 ((bfd_vma) ZEROS, frag + 4);
2809
+ if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
2810
+ fix_new_exp (frag_now, where, 2,
2811
+ &(op1.exp), FALSE, CHECK_RELOC_MSP430X_SRC);
2813
+ fix_new_exp (frag_now, where , 2,
2814
+ &(op1.exp), TRUE, CHECK_RELOC_MSP430X_PCREL_SRC);
2817
+ if (op2.mode == OP_EXP)
2820
+ x(Rn). x can be odd in non-byte operations
2821
+ except x(R2) = x(0) = &TONI and x(PC) = TONI
2823
+ imm_op = (op2.mode == 1 && op2.reg != 2 && op2.reg != 0);
2824
+ bfd_putl16 ((bfd_vma) ZEROS, frag + 4 + ((__is == 4) ? 2 : 0));
2826
+ if (op1.mode == OP_EXP)
2828
+ if (op2.reg) /* Not PC relative. */
2829
+ fix_new_exp (frag_now, where, 2,
2830
+ &(op2.exp), FALSE, CHECK_RELOC_MSP430X_DST_2ND);
2832
+ fix_new_exp (frag_now, where, 2,
2833
+ &(op2.exp), TRUE, CHECK_RELOC_MSP430X_PCREL_DST_2ND);
2837
+ if (op2.reg) /* Not PC relative. */
2838
+ fix_new_exp (frag_now, where, 2,
2839
+ &(op2.exp), FALSE, CHECK_RELOC_MSP430X_DST);
2841
+ fix_new_exp (frag_now, where, 2,
2842
+ &(op2.exp), TRUE, CHECK_RELOC_MSP430X_PCREL_DST);
2847
+ case FMT_X_SINGLE_OPERAND: /* Extended format 2 (single-operand). */
2848
+ l1 = get_operand ();
2849
+ res = msp430_srcoperand (&op1, l1, &imm_op, -(1<<19), (1<<20));
2850
+ msp430_substitute_CG(&op1, 0);
2852
+ break; /* Error in operand. */
2854
+ if (opcode_variant(opcode) != V_PUSHX && op1.mode == OP_EXP && op1.am == 3) // #N
2856
+ as_bad (_("bad operand [%s]"), l1);
2860
+ if (msp430x_repeats)
2862
+ if (op1.mode != OP_REG)
2864
+ as_bad(_("Repeated instruction must have register mode operand"));
2867
+ bin |= msp430x_repeats >> 1;
2868
+ msp430x_repeats = 0;
2871
+ if(opcode_variant(opcode) == V_SWPSXT && op_width == ADDR_OP)
2872
+ { // sxtx.a | swpbx.a opcode
2873
+ bin ^= BYTE_OPERATION_X;
2876
+ bin |= (op1.reg | (op1.am << 4)) << 16;
2877
+ __is = 2 + op1.ol; /* insn size in words, opcode is 2 words wide. */
2878
+ frag = frag_more (2 * __is);
2879
+ where = frag - frag_now->fr_literal;
2880
+ bfd_putl32 ((bfd_vma) bin, frag);
2881
+ dwarf2_emit_insn (2 * __is);
2883
+ if (op1.mode == OP_EXP)
2885
+ bfd_putl16 ((bfd_vma) ZEROS, frag + 4);
2887
+ if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
2888
+ fix_new_exp (frag_now, where, 2,
2889
+ &(op1.exp), FALSE, CHECK_RELOC_MSP430X_DST);
2891
+ fix_new_exp (frag_now, where, 2,
2892
+ &(op1.exp), TRUE, CHECK_RELOC_MSP430X_PCREL_DST);
2896
+ case FMT_X_EXCEPTION:
2897
+ /* calla, pushm, popm, rrcm, rrum, rram, rlam */
2898
+ bin = opcode->bin_opcode; // remove WB/AL bits
2899
+ l1 = get_operand ();
2900
+ switch(opcode_variant(opcode))
2902
+ case V_CALLA: // calla
2903
+ res = msp430_srcoperand (&op1, l1, &imm_op, -(1<<19), (1<<20));
2905
+ break; /* Error in operand. */
2906
+ __is = 1 + op1.ol;
2907
+ frag = frag_more(__is * 2);
2909
+ if (op1.mode == OP_REG)
2925
+ bfd_putl16 ((bfd_vma) bin, frag);
2926
+ dwarf2_emit_insn (__is * 2);
2928
+ else if (op1.mode == OP_EXP)
2930
+ bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
2931
+ where = frag - frag_now->fr_literal;
2937
+ case 0: // x(PC) = EDE
2939
+ bfd_putl16 ((bfd_vma) bin, frag);
2940
+ fix_new_exp (frag_now, where, 2,
2941
+ &(op1.exp), TRUE, BFD_RELOC_MSP430X_PCREL_D);
2945
+ bfd_putl16 ((bfd_vma) bin, frag);
2946
+ fix_new_exp (frag_now, where, 2,
2947
+ &(op1.exp), FALSE, BFD_RELOC_MSP430X_D);
2949
+ default: //z16(Rdst)
2950
+ bin |= 0x0050 | op1.reg;
2951
+ bfd_putl16 ((bfd_vma) bin, frag);
2952
+ fix_new_exp (frag_now, where, 2,
2953
+ &(op1.exp), FALSE, BFD_RELOC_MSP430X_INDXD);
2957
+ case 3: // calla #imm
2959
+ bfd_putl16 ((bfd_vma) bin, frag);
2960
+ fix_new_exp (frag_now, where, 2,
2961
+ &(op1.exp), FALSE, BFD_RELOC_MSP430X_D);
2964
+ dwarf2_emit_insn (__is * 2);
2967
+ case V_ROTM: // rxxm
2968
+ l2 = get_operand ();
2969
+ res = msp430_srcoperand (&op1, l1, &imm_op, 1, 5);
2970
+ res += msp430_dstoperand (&op2, l2, -(1<<19), (1<<20));
2972
+ break; /* An error occurred. All warnings were done before. */
2974
+ if(op_width != ADDR_OP)
2977
+ if(op1.mode != OP_EXP || op1.am != 3) // not #imm
2979
+ as_bad (_("bad operand [%s]"), l1);
2983
+ bin |= ((op1.exp.X_add_number - 1) & 0x0003) << 10;
2985
+ if(op2.mode != OP_REG)
2987
+ as_bad (_("bad operand [%s]"), l2);
2992
+ frag = frag_more (2);
2993
+ bfd_putl16 ((bfd_vma) bin, frag);
2994
+ dwarf2_emit_insn (2);
2998
+ l2 = get_operand ();
2999
+ res = msp430_srcoperand (&op1, l1, &imm_op, 1, 17);
3000
+ res += msp430_dstoperand (&op2, l2, -(1<<19), (1<<20));
3002
+ break; /* An error occurred. All warnings were done before. */
3007
+ as_bad (_("bad operand [%s]"), l1);
3011
+ if(op_width != ADDR_OP)
3015
+ bin |= ((op1.exp.X_add_number - 1) & 0x000F) << 4;
3017
+ if(op2.mode != OP_REG)
3019
+ as_bad (_("bad operand [%s]"), l2);
3022
+ if(opcode_variant(opcode) == V_POPM)
3025
+ bin |= (op2.reg - op1.exp.X_add_number + 1) & 0x000F;
3033
+ frag = frag_more (2);
3034
+ bfd_putl16 ((bfd_vma) bin, frag);
3035
+ dwarf2_emit_insn (2);
3039
+ case FMT_X_ADDRESS:
3040
+ /* mova, adda, suba, cmpa */
3041
+ l1 = get_operand ();
3042
+ l2 = get_operand ();
3043
+ res = msp430_srcoperand (&op1, l1, &imm_op, -(1<<19), (1<<20));
3044
+ res += msp430_dstoperand (&op2, l2, -(1<<19), (1<<20));
3046
+ break; /* Error in operand. */
3048
+ __is = 1 + op1.ol + op2.ol;
3049
+ frag = frag_more(__is * 2);
3050
+ where = frag - frag_now->fr_literal;
3051
+ bin = opcode->bin_opcode; // remove WB/AL bits
3052
+ if( opcode_variant(opcode) == V_MOVA)
3054
+ if (op1.mode == OP_REG && op1.am == 0)
3056
+ if(op2.mode == OP_REG && op2.am == 0)
3058
+ // mova Rsrc, Rdst
3059
+ bin |= 0x00c0 | op1.reg << 8 | op2.reg;
3060
+ bfd_putl16 ((bfd_vma) bin, frag);
3061
+ dwarf2_emit_insn (__is * 2);
3063
+ else if(op2.mode == OP_EXP && op2.am == 1 && op2.reg == 2)
3065
+ // mova Rsrc, &abs20
3066
+ bin |= 0x0060 | op1.reg << 8;
3067
+ bfd_putl16 ((bfd_vma) bin, frag);
3068
+ dwarf2_emit_insn (__is * 2);
3069
+ bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
3070
+ fix_new_exp (frag_now, where, 2,
3071
+ &(op2.exp), FALSE, BFD_RELOC_MSP430X_D);
3073
+ else if(op2.mode == OP_EXP && op2.am == 1 && op2.reg == 0)
3075
+ bin |= 0x0070 | op1.reg << 8;
3076
+ bfd_putl16 ((bfd_vma) bin, frag);
3077
+ dwarf2_emit_insn (__is * 2);
3078
+ bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
3079
+ fix_new_exp (frag_now, where, 2,
3080
+ &(op2.exp), TRUE, BFD_RELOC_MSP430X_PCREL_D);
3082
+ else if(op2.mode == OP_EXP && op2.am == 1)
3084
+ // mova Rsrc, z16(Rdst)
3085
+ bin |= 0x0070 | op1.reg << 8 | op2.reg;
3086
+ bfd_putl16 ((bfd_vma) bin, frag);
3087
+ dwarf2_emit_insn (__is * 2);
3088
+ bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
3090
+ // mova Rsrc, TONI == mova Rsrc, z16(PC)
3091
+ fix_new_exp (frag_now, where, 2,
3092
+ &(op2.exp), TRUE, BFD_RELOC_MSP430X_PCREL_INDXD);
3094
+ fix_new_exp (frag_now, where, 2,
3095
+ &(op2.exp), FALSE, BFD_RELOC_MSP430X_INDXD);
3098
+ as_bad (_("destination operand address mode not allowed with mova instruction"));
3101
+ else if (op2.mode == OP_REG && op2.am == 0)
3103
+ if(op1.mode == OP_REG && op1.am == 2)
3105
+ // mova @Rsrc, Rdst
3106
+ bin |= 0x0000 | op1.reg << 8 | op2.reg;
3107
+ bfd_putl16 ((bfd_vma) bin, frag);
3108
+ dwarf2_emit_insn (__is * 2);
3110
+ else if (op1.mode == OP_REG && op1.am == 3)
3112
+ // mova @Rsrc+, Rdst
3113
+ bin |= 0x0010 | op1.reg << 8 | op2.reg;
3114
+ bfd_putl16 ((bfd_vma) bin, frag);
3115
+ dwarf2_emit_insn (__is * 2);
3117
+ else if (op1.mode == OP_EXP && op1.am == 1 && op1.reg == 2)
3121
+ // mova &abs20, Rdst
3122
+ bin |= 0x0020 | op2.reg;
3123
+ bfd_putl16 ((bfd_vma) bin, frag);
3124
+ dwarf2_emit_insn (__is * 2);
3125
+ bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
3126
+ fix_new_exp (frag_now, where, 2,
3127
+ &(op1.exp), FALSE, BFD_RELOC_MSP430X_S);
3131
+ // mova z16(Rsrc), Rdst
3132
+ bin |= 0x0030 | op1.reg << 8 | op2.reg;
3133
+ bfd_putl16 ((bfd_vma) bin, frag);
3134
+ dwarf2_emit_insn (__is * 2);
3135
+ bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
3137
+ // mova TONI, Rdst
3138
+ fix_new_exp (frag_now, where, 2,
3139
+ &(op1.exp), FALSE, BFD_RELOC_MSP430X_PCREL_INDXD);
3141
+ fix_new_exp (frag_now, where, 2,
3142
+ &(op1.exp), FALSE, BFD_RELOC_MSP430X_INDXD);
3145
+ else if (op1.mode == OP_EXP && op1.am == 3)
3147
+ // mova #imm20, Rdst
3148
+ bin |= 0x0080 | op2.reg;
3149
+ bfd_putl16 ((bfd_vma) bin, frag);
3150
+ dwarf2_emit_insn (__is * 2);
3151
+ bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
3153
+ fix_new_exp (frag_now, where, 2,
3154
+ &(op1.exp), FALSE, BFD_RELOC_MSP430X_S);
3156
+ fix_new_exp (frag_now, where, 2,
3157
+ &(op1.exp), FALSE, BFD_RELOC_MSP430X_S_BYTE);
3160
+ as_bad (_("source operand address mode not allowed with mova instruction"));
3165
+ /* adda, suba, cmpa */
3167
+ if(op2.mode == OP_REG && op2.am == 0)
3169
+ if (op1.mode == OP_REG && op1.am == 0)
3171
+ bin |= 0x0040 | op1.reg << 8 | op2.reg;
3172
+ bfd_putl16 ((bfd_vma) bin, frag);
3173
+ dwarf2_emit_insn (__is * 2);
3175
+ else if (op1.mode == OP_EXP && op1.am == 3)
3178
+ bin |= 0x0080 | op2.reg;
3179
+ bfd_putl16 ((bfd_vma) bin, frag);
3180
+ dwarf2_emit_insn (__is * 2);
3181
+ bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
3183
+ fix_new_exp (frag_now, where, 2,
3184
+ &(op1.exp), FALSE, BFD_RELOC_MSP430X_S);
3186
+ fix_new_exp (frag_now, where, 2,
3187
+ &(op1.exp), FALSE, BFD_RELOC_MSP430X_S_BYTE);
3190
+ as_bad (_("source operand address mode not allowed with %s instruction"), opcode->name);
3193
+ as_bad (_("destination operand address mode not allowed with %s instruction"), opcode->name);
3198
+ case FMT_X_EMULATED: /* Extended emulated. */
3199
+ switch (opcode_variant(opcode))
3202
+ /* single operand instruction emulated with Extended type 1 (double operand) instructions. */
3203
+ l1 = get_operand ();
3204
+ res = msp430_dstoperand (&op1, l1, -(1<<19), (1<<20) );
3208
+ if (msp430x_repeats)
3210
+ if ((bin >> 20) && 0x3 == 1)
3212
+ as_bad (_("%s instruction is not repeatable"), opcode->name);
3215
+ if (op1.mode != OP_REG)
3217
+ as_bad(_("Repeated instruction must have register mode operand"));
3220
+ bin |= msp430x_repeats >> 1;
3221
+ msp430x_repeats = 0;
3224
+ bin |= (op1.reg | (op1.am << 7)) << 16;
3225
+ __is = 2 + op1.ol;
3226
+ frag = frag_more (2 * __is);
3227
+ where = frag - frag_now->fr_literal;
3228
+ bfd_putl32 ((bfd_vma) bin, frag);
3229
+ dwarf2_emit_insn (2 * __is);
3231
+ if (op1.mode == OP_EXP)
3234
+ x(Rn). x can be odd in non-byte operations
3235
+ except x(R2) = x(0) = &TONI and x(PC) = TONI
3237
+ imm_op = (op2.mode == 1 && op2.reg != 2 && op2.reg != 0);
3239
+ bfd_putl16 ((bfd_vma) ZEROS, frag + 4);
3240
+ if (op1.reg || (op1.reg == 0 && op1.am == 3))
3241
+ fix_new_exp (frag_now, where, 2,
3242
+ &(op1.exp), FALSE, CHECK_RELOC_MSP430X_DST);
3244
+ fix_new_exp (frag_now, where, 2,
3245
+ &(op1.exp), TRUE, CHECK_RELOC_MSP430X_PCREL_DST);
3250
+ /* Shift instruction. */
3251
+ l1 = get_operand ();
3252
+ res = msp430_srcoperand (&op1, l1, &imm_op, -(1<<19), (1<<20));
3253
+ msp430_substitute_CG(&op1, 0);
3254
+ res += msp430_dstoperand (&op2, l1, -(1<<19), (1<<20));
3257
+ break; /* An error occurred. All warnings were done before. */
3259
+ if (msp430x_repeats)
3261
+ if (op2.mode != OP_REG)
3263
+ as_bad(_("Repeated instruction must have register mode operands"));
3266
+ bin |= msp430x_repeats >> 1;
3267
+ msp430x_repeats = 0;
3270
+ bin |= (op2.reg | (op1.reg << 8) | (op1.am << 4) | (op2.am << 7)) << 16;
3272
+ __is = 2 + op1.ol + op2.ol; /* insn size in words. */
3273
+ frag = frag_more (2 * __is);
3274
+ where = frag - frag_now->fr_literal;
3275
+ bfd_putl32 ((bfd_vma) bin, frag);
3276
+ dwarf2_emit_insn (2 * __is);
3278
+ if (op1.mode == OP_EXP)
3280
+ bfd_putl16 ((bfd_vma) ZEROS, frag + 4);
3282
+ if (op1.reg || (op1.reg == 0 && op1.am == 3)) /* Not PC relative. */
3283
+ fix_new_exp (frag_now, where, 2,
3284
+ &(op1.exp), FALSE, CHECK_RELOC_MSP430X_SRC);
3286
+ fix_new_exp (frag_now, where, 2,
3287
+ &(op1.exp), TRUE, CHECK_RELOC_MSP430X_PCREL_SRC);
3290
+ if (op2.mode == OP_EXP)
3293
+ x(Rn). x can be odd in non-byte operations
3294
+ except x(R2) = x(0) = &TONI and x(PC) = TONI
3296
+ imm_op = (op2.mode == 1 && op2.reg != 2 && op2.reg != 0);
3298
+ bfd_putl16 ((bfd_vma) ZEROS, frag + 4 + ((__is == 4) ? 2 : 0));
3299
+ if (op1.mode == OP_EXP)
3302
+ if (op2.reg) /* Not PC relative. */
3303
+ fix_new_exp (frag_now, where, 2,
3304
+ &(op2.exp), FALSE, CHECK_RELOC_MSP430X_DST_2ND);
3306
+ fix_new_exp (frag_now, where, 2,
3307
+ &(op2.exp), TRUE, CHECK_RELOC_MSP430X_PCREL_DST_2ND);
3312
+ if (op2.reg) /* Not PC relative. */
3313
+ fix_new_exp (frag_now, where, 2,
3314
+ &(op2.exp), FALSE, CHECK_RELOC_MSP430X_DST);
3316
+ fix_new_exp (frag_now, where, 2,
3317
+ &(op2.exp), TRUE, CHECK_RELOC_MSP430X_PCREL_DST);
3324
+ if (msp430x_repeats)
3326
+ as_bad (_("%s instruction is not repeatable"), opcode->name);
3329
+ bin = opcode->bin_opcode; // remove WB/AL bits
3330
+ frag = frag_more (2);
3331
+ bfd_putl16 ((bfd_vma) bin, frag);
3332
+ dwarf2_emit_insn (2);
3334
+ case V_EMU_ADDR: // incda, decda, tsta
3335
+ if (msp430x_repeats)
3337
+ as_bad (_("%s instruction is not repeatable"), opcode->name);
3340
+ bin = opcode->bin_opcode; // remove WB/AL bits
3341
+ l1 = get_operand ();
3342
+ res = msp430_dstoperand (&op1, l1, -(1<<19), (1<<20) );
3346
+ if(op1.mode == OP_REG && op1.am == 0)
3348
+ frag = frag_more(2);
3350
+ bfd_putl16 ((bfd_vma) bin, frag);
3351
+ dwarf2_emit_insn (2);
3354
+ as_bad (_("destination operand address mode not allowed with %s instruction"), opcode->name);
3356
+ case V_BRA: // bra, emulated with Address type instruction
3357
+ if (msp430x_repeats)
3359
+ as_bad (_("%s instruction is not repeatable"), opcode->name);
3363
+ bin = opcode->bin_opcode; // remove WB/AL bits
3364
+ l1 = get_operand ();
3365
+ res = msp430_srcoperand (&op1, l1, &imm_op, -(1<<19), (1<<20));
3367
+ break; /* Error in operand. */
3369
+ __is = 1 + op1.ol;
3370
+ frag = frag_more(__is * 2);
3371
+ where = frag - frag_now->fr_literal;
3372
+ if (op1.mode == OP_REG && op1.am == 0)
3375
+ bin |= 0x00C0 | op1.reg << 8;
3376
+ bfd_putl16 ((bfd_vma) bin, frag);
3377
+ dwarf2_emit_insn (__is * 2);
3379
+ else if(op1.mode == OP_REG && op1.am == 2)
3382
+ bin |= 0x0000 | op1.reg << 8;
3383
+ bfd_putl16 ((bfd_vma) bin, frag);
3384
+ dwarf2_emit_insn (__is * 2);
3386
+ else if (op1.mode == OP_REG && op1.am == 3)
3388
+ // mova @Rsrc+, PC
3389
+ bin |= 0x0010 | op1.reg << 8;
3390
+ bfd_putl16 ((bfd_vma) bin, frag);
3391
+ dwarf2_emit_insn (__is * 2);
3393
+ else if (op1.mode == OP_EXP && op1.am == 1)
3397
+ // mova &abs20, PC
3399
+ bfd_putl16 ((bfd_vma) bin, frag);
3400
+ dwarf2_emit_insn (__is * 2);
3401
+ bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
3402
+ fix_new_exp (frag_now, where, 2,
3403
+ &(op1.exp), FALSE, BFD_RELOC_MSP430X_S);
3407
+ // mova z16(Rsrc), PC
3408
+ bin |= 0x0030 | op1.reg << 8;
3409
+ bfd_putl16 ((bfd_vma) bin, frag);
3410
+ dwarf2_emit_insn (__is * 2);
3411
+ bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
3413
+ // mova z16(PC), PC = mova TONI, PC
3414
+ fix_new_exp (frag_now, where, 2,
3415
+ &(op1.exp), TRUE, BFD_RELOC_MSP430X_PCREL_INDXD);
3417
+ fix_new_exp (frag_now, where, 2,
3418
+ &(op1.exp), FALSE, BFD_RELOC_MSP430X_INDXD);
3421
+ else if (op1.mode == OP_EXP && op1.am == 3)
3423
+ // mova #imm20, Rdst
3425
+ bfd_putl16 ((bfd_vma) bin, frag);
3426
+ dwarf2_emit_insn (__is * 2);
3427
+ bfd_putl16 ((bfd_vma) ZEROS, frag + 2);
3428
+ fix_new_exp (frag_now, where, 2,
3429
+ &(op1.exp), FALSE, BFD_RELOC_MSP430X_S);
3432
+ as_bad (_("source operand address mode not allowed with bra instruction"));
3437
as_bad (_("Illegal instruction or not implemented opcode."));
3440
- input_line_pointer = line;
3450
md_assemble (char * str)
3452
- struct msp430_opcode_s * opcode;
3454
- unsigned int i = 0;
3456
- str = skip_space (str); /* Skip leading spaces. */
3457
- str = extract_cmd (str, cmd, sizeof (cmd));
3459
- while (cmd[i] && i < sizeof (cmd))
3461
- char a = TOLOWER (cmd[i]);
3467
+ struct msp430_opcode_s const * opcode;
3473
+ while (ISSPACE (*str))
3476
+ while (*str && (! ISSPACE (*str)) && '.' != *str)
3478
+ cmd_length = str - cmd;
3479
+ if (0 == cmd_length)
3481
as_bad (_("can't find opcode "));
3485
- opcode = (struct msp430_opcode_s *) hash_find (msp430_hash, cmd);
3486
+ cmda = alloca(1+cmd_length);
3488
+ cmda[i] = TOLOWER(cmd[i]);
3489
+ } while (++i < cmd_length);
3492
+ opcode = (struct msp430_opcode_s const *) hash_find (msp430_hash, cmda);
3496
- as_bad (_("unknown opcode `%s'"), cmd);
3497
+ as_bad (_("unknown opcode `%s'"), cmda);
3501
+ if (msp430_cpu < MSP430_CPU_MSP430X && opcode_format(opcode) >= FMT_X)
3503
+ as_bad (_("Extended instruction (%s) requires 430X-based mcu"), opcode->name);
3507
@@ -1963,6 +3025,26 @@ md_apply_fix (fixS * fixp, valueT * valuep, segT seg)
3509
switch (fixp->fx_r_type)
3511
+ case BFD_RELOC_MSP430X_PCREL_D:
3512
+ case BFD_RELOC_MSP430X_PCREL_INDXD:
3513
+ value -= 2; // operand located 2 bytes after opcode
3515
+ case BFD_RELOC_MSP430X_PCREL_SRC:
3516
+ case BFD_RELOC_MSP430X_PCREL_SRC_BYTE:
3517
+ case BFD_RELOC_MSP430X_PCREL_DST:
3518
+ case BFD_RELOC_MSP430X_PCREL_DST_BYTE:
3519
+ value -= 4; // operand located 4 bytes after opcode
3521
+ case BFD_RELOC_MSP430X_PCREL_DST_2ND:
3522
+ case BFD_RELOC_MSP430X_PCREL_DST_2ND_BYTE:
3523
+ value -= 6; // operand located 6 bytes after opcode
3529
+ switch (fixp->fx_r_type)
3531
case BFD_RELOC_MSP430_10_PCREL:
3533
as_bad_where (fixp->fx_file, fixp->fx_line,
3534
@@ -1987,7 +3069,7 @@ md_apply_fix (fixS * fixp, valueT * valuep, segT seg)
3535
_("odd address operand: %ld"), value);
3537
/* Nothing to be corrected here. */
3538
- if (value < -32768 || value > 65536)
3539
+ if (value < -32768 || value > 65535)
3540
as_bad_where (fixp->fx_file, fixp->fx_line,
3541
_("operand out of range: %ld"), value);
3543
@@ -1997,7 +3079,7 @@ md_apply_fix (fixS * fixp, valueT * valuep, segT seg)
3545
case BFD_RELOC_MSP430_16_PCREL_BYTE:
3546
/* Nothing to be corrected here. */
3547
- if (value < -32768 || value > 65536)
3548
+ if (value < -32768 || value > 65535)
3549
as_bad_where (fixp->fx_file, fixp->fx_line,
3550
_("operand out of range: %ld"), value);
3552
@@ -2016,6 +3098,76 @@ md_apply_fix (fixS * fixp, valueT * valuep, segT seg)
3553
bfd_putl16 ((bfd_vma) value, where);
3556
+ case BFD_RELOC_MSP430X_SRC:
3557
+ case BFD_RELOC_MSP430X_PCREL_SRC:
3559
+ as_bad_where (fixp->fx_file, fixp->fx_line,
3560
+ _("odd operand: %ld"), value);
3561
+ case BFD_RELOC_MSP430X_SRC_BYTE:
3562
+ case BFD_RELOC_MSP430X_PCREL_SRC_BYTE:
3564
+ bfd_putl16 ((bfd_vma)(bfd_getl16 (where) & 0xf87f) | ((value >> 9) & 0x0780), where);
3565
+ /* 16 least-significant bits */
3566
+ bfd_putl16 ((bfd_vma) (value & 0xffff), where + 4);
3568
+ case BFD_RELOC_MSP430X_DST:
3569
+ case BFD_RELOC_MSP430X_PCREL_DST:
3571
+ as_bad_where (fixp->fx_file, fixp->fx_line,
3572
+ _("odd operand: %ld"), value);
3573
+ case BFD_RELOC_MSP430X_DST_BYTE:
3574
+ case BFD_RELOC_MSP430X_PCREL_DST_BYTE:
3575
+ bfd_putl16 ((bfd_vma)(bfd_getl16 (where) & 0xfff0) | ((value >> 16) & 0x000f), where);
3576
+ /* 16 least-significant bits */
3578
+ bfd_putl16 ((bfd_vma) (value & 0xffff), where + 4);
3580
+ case BFD_RELOC_MSP430X_DST_2ND:
3581
+ case BFD_RELOC_MSP430X_PCREL_DST_2ND:
3583
+ as_bad_where (fixp->fx_file, fixp->fx_line,
3584
+ _("odd operand: %ld"), value);
3585
+ case BFD_RELOC_MSP430X_DST_2ND_BYTE:
3586
+ case BFD_RELOC_MSP430X_PCREL_DST_2ND_BYTE:
3588
+ bfd_putl16 ((bfd_vma)(bfd_getl16 (where) & 0xfff0) | ((value >> 16) & 0x000f), where);
3589
+ /* 16 least-significant bits */
3590
+ bfd_putl16 ((bfd_vma) (value & 0xffff), where + 6);
3592
+ case BFD_RELOC_MSP430X_S:
3594
+ as_bad_where (fixp->fx_file, fixp->fx_line,
3595
+ _("odd operand: %ld"), value);
3596
+ case BFD_RELOC_MSP430X_S_BYTE:
3598
+ bfd_putl16 ((bfd_vma)(bfd_getl16 (where) & 0xf0ff) | ((value >> 8) & 0x0f00), where);
3599
+ /* 16 least-significant bits */
3600
+ bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
3602
+ case BFD_RELOC_MSP430X_D:
3603
+ case BFD_RELOC_MSP430X_PCREL_D:
3605
+ as_bad_where (fixp->fx_file, fixp->fx_line,
3606
+ _("odd operand: %ld"), value);
3607
+ case BFD_RELOC_MSP430X_D_BYTE:
3609
+ bfd_putl16 ((bfd_vma)(bfd_getl16 (where) & 0xfff0) | ((value >> 16) & 0x000f), where);
3610
+ /* 16 least-significant bits */
3611
+ bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
3613
+ case BFD_RELOC_MSP430X_PCREL_INDXD:
3615
+ as_bad_where (fixp->fx_file, fixp->fx_line,
3616
+ _("odd operand: %ld"), value);
3617
+ case BFD_RELOC_MSP430X_INDXD:
3618
+ if (value < -32768 || value > 65535)
3619
+ as_bad_where (fixp->fx_file, fixp->fx_line,
3620
+ _("operand out of range: %ld"), value);
3622
+ value &= 0xffff; /* Get rid of extended sign. */
3623
+ bfd_putl16 ((bfd_vma) value, where + 2);
3627
as_fatal (_("line %d: unknown relocation type: 0x%x"),
3628
fixp->fx_line, fixp->fx_r_type);
3629
diff --git a/gas/testsuite/gas/msp430/opcode.d b/gas/testsuite/gas/msp430/opcode.d
3630
index 22df51c..297d3e1 100644
3631
--- a/gas/testsuite/gas/msp430/opcode.d
3632
+++ b/gas/testsuite/gas/msp430/opcode.d
3635
Disassembly of section .text:
3636
0+000 <[^>]*> 1b f3 and #1, r11 ;r3 As==01
3637
-0+002 <[^>]*> 3a e3 inv r10 ;
3638
+0+002 <[^>]*> 3a e3 inv r10
3639
0+004 <[^>]*> 3b e0 ff 00 xor #255, r11 ;#0x00ff
3640
0+008 <[^>]*> 3c d2 bis #8, r12 ;r2 As==11
3641
0+00a <[^>]*> 3d b0 10 00 bit #16, r13 ;#0x0010
3642
0+00e <[^>]*> 3e c0 a0 00 bic #160, r14 ;#0x00a0
3643
-0+012 <[^>]*> 0f 93 cmp #0, r15 ;r3 As==00
3644
-0+014 <[^>]*> 1a 83 dec r10 ;
3645
-0+016 <[^>]*> 0b 73 sbc r11 ;
3646
-0+018 <[^>]*> 1c 53 inc r12 ;
3647
+0+012 <[^>]*> 0f 93 tst r15
3648
+0+014 <[^>]*> 1a 83 dec r10
3649
+0+016 <[^>]*> 0b 73 sbc r11
3650
+0+018 <[^>]*> 1c 53 inc r12
3651
0+01a <[^>]*> 2d 63 addc #2, r13 ;r3 As==10
3652
-0+01c <[^>]*> 0e 12 push r14 ;
3653
-0+01e <[^>]*> 3f 41 pop r15 ;
3654
-0+020 <[^>]*> 8a 11 sxt r10 ;
3655
-0+022 <[^>]*> 0b 11 rra r11 ;
3656
-0+024 <[^>]*> 8c 10 swpb r12 ;
3657
-0+026 <[^>]*> 0d 10 rrc r13 ;
3658
+0+01c <[^>]*> 0e 12 push r14
3659
+0+01e <[^>]*> 3f 41 pop r15
3660
+0+020 <[^>]*> 8a 11 sxt r10
3661
+0+022 <[^>]*> 0b 11 rra r11
3662
+0+024 <[^>]*> 8c 10 swpb r12
3663
+0+026 <[^>]*> 0d 10 rrc r13
3664
0+028 <[^>]*> 30 41 ret
3665
0+02a <[^>]*> 31 40 00 00 mov #0, r1 ;#0x0000
3666
-0+02e <[^>]*> b0 12 00 00 call #0 ;#0x0000
3667
-0+032 <[^>]*> 1e 42 00 00 mov &0x0000,r14 ;0x0000
3668
-0+036 <[^>]*> 0f 4e mov r14, r15 ;
3669
-0+038 <[^>]*> 0f 5f rla r15 ;
3670
-0+03a <[^>]*> 0f 7f subc r15, r15 ;
3671
-0+03c <[^>]*> 3f e3 inv r15 ;
3672
-0+03e <[^>]*> b0 12 00 00 call #0 ;#0x0000
3673
-0+042 <[^>]*> 82 4e 00 00 mov r14, &0x0000 ;
3674
-0+046 <[^>]*> 82 4f 00 00 mov r15, &0x0000 ;
3675
-0+04a <[^>]*> 1e 42 00 00 mov &0x0000,r14 ;0x0000
3676
-0+04e <[^>]*> 0f 4e mov r14, r15 ;
3677
-0+050 <[^>]*> 0f 5f rla r15 ;
3678
-0+052 <[^>]*> 0f 7f subc r15, r15 ;
3679
-0+054 <[^>]*> 3f e3 inv r15 ;
3680
-0+056 <[^>]*> b0 12 00 00 call #0 ;#0x0000
3681
-0+05a <[^>]*> 82 4e 00 00 mov r14, &0x0000 ;
3682
-0+05e <[^>]*> 82 4f 00 00 mov r15, &0x0000 ;
3683
+0+02e <[^>]*> b0 12 00 00 call #0x0000
3684
+0+032 <[^>]*> 1e 42 00 00 mov &0x0000,r14
3685
+0+036 <[^>]*> 0f 4e mov r14, r15
3686
+0+038 <[^>]*> 0f 5f rla r15
3687
+0+03a <[^>]*> 0f 7f subc r15, r15
3688
+0+03c <[^>]*> 3f e3 inv r15
3689
+0+03e <[^>]*> b0 12 00 00 call #0x0000
3690
+0+042 <[^>]*> 82 4e 00 00 mov r14, &0x0000
3691
+0+046 <[^>]*> 82 4f 00 00 mov r15, &0x0000
3692
+0+04a <[^>]*> 1e 42 00 00 mov &0x0000,r14
3693
+0+04e <[^>]*> 0f 4e mov r14, r15
3694
+0+050 <[^>]*> 0f 5f rla r15
3695
+0+052 <[^>]*> 0f 7f subc r15, r15
3696
+0+054 <[^>]*> 3f e3 inv r15
3697
+0+056 <[^>]*> b0 12 00 00 call #0x0000
3698
+0+05a <[^>]*> 82 4e 00 00 mov r14, &0x0000
3699
+0+05e <[^>]*> 82 4f 00 00 mov r15, &0x0000
3700
0+062 <[^>]*> 3f 40 f0 00 mov #240, r15 ;#0x00f0
3701
-0+066 <[^>]*> 30 40 00 00 br #0x0000 ;
3702
-0+06a <[^>]*> 92 52 00 02 72 01 add &0x0200,&0x0172 ;0x0200
3703
+0+066 <[^>]*> 30 40 00 00 br #0x0000
3704
+0+06a <[^>]*> 92 52 00 02 72 01 add &0x0200,&0x0172
3705
+0+070 <extract> 3a 40 f0 de mov #-8464, r10 ;#0xdef0
3706
+0+074 <extract\+0x4> 3b 40 bc 9a mov #-25924,r11 ;#0x9abc
3707
+0+078 <extract\+0x8> 3c 40 78 56 mov #22136, r12 ;#0x5678
3708
+0+07c <extract\+0xc> 3d 40 34 12 mov #4660, r13 ;#0x1234
3709
+0+080 <extract0> 3a 40 7b 00 mov #123, r10 ;#0x007b
3710
+0+084 <extract0\+0x4> 0b 43 clr r11
3711
+0+086 <extract0\+0x6> 0c 43 clr r12
3712
+0+088 <extract0\+0x8> 0d 43 clr r13
3713
diff --git a/gas/testsuite/gas/msp430/opcode.s b/gas/testsuite/gas/msp430/opcode.s
3714
index b85a463..8fa444f 100644
3715
--- a/gas/testsuite/gas/msp430/opcode.s
3716
+++ b/gas/testsuite/gas/msp430/opcode.s
3717
@@ -55,3 +55,19 @@ main:
3718
;; This next instruction triggered a bug which
3719
;; was fixed by a patch to msp430-dis.c on Jan 2, 2004
3723
+ .type extract,@function
3725
+ mov #llo(0x123456789abcdef0), r10
3726
+ mov #lhi(0x123456789abcdef0), r11
3727
+ mov #hlo(0x123456789abcdef0), r12
3728
+ mov #hhi(0x123456789abcdef0), r13
3731
+ .type extract,@function
3733
+ mov #llo(123), r10
3734
+ mov #lhi(123), r11
3735
+ mov #hlo(123), r12
3736
+ mov #hhi(123), r13
3737
diff --git a/include/elf/msp430.h b/include/elf/msp430.h
3738
index 44f5c51..1eeb56b 100644
3739
--- a/include/elf/msp430.h
3740
+++ b/include/elf/msp430.h
3743
#include "elf/reloc-macros.h"
3745
-/* Processor specific flags for the ELF header e_flags field. */
3746
-#define EF_MSP430_MACH 0xff
3748
-#define E_MSP430_MACH_MSP430x11 11
3749
-#define E_MSP430_MACH_MSP430x11x1 110
3750
-#define E_MSP430_MACH_MSP430x12 12
3751
-#define E_MSP430_MACH_MSP430x13 13
3752
-#define E_MSP430_MACH_MSP430x14 14
3753
-#define E_MSP430_MACH_MSP430x15 15
3754
-#define E_MSP430_MACH_MSP430x16 16
3755
-#define E_MSP430_MACH_MSP430x31 31
3756
-#define E_MSP430_MACH_MSP430x32 32
3757
-#define E_MSP430_MACH_MSP430x33 33
3758
-#define E_MSP430_MACH_MSP430x41 41
3759
-#define E_MSP430_MACH_MSP430x42 42
3760
-#define E_MSP430_MACH_MSP430x43 43
3761
-#define E_MSP430_MACH_MSP430x44 44
3764
START_RELOC_NUMBERS (elf_msp430_reloc_type)
3765
RELOC_NUMBER (R_MSP430_NONE, 0)
3766
@@ -52,7 +34,71 @@ START_RELOC_NUMBERS (elf_msp430_reloc_type)
3767
RELOC_NUMBER (R_MSP430_16_PCREL_BYTE, 6)
3768
RELOC_NUMBER (R_MSP430_2X_PCREL, 7)
3769
RELOC_NUMBER (R_MSP430_RL_PCREL, 8)
3770
+ RELOC_NUMBER (R_MSP430X_SRC_BYTE, 9)
3771
+ RELOC_NUMBER (R_MSP430X_SRC, 10)
3772
+ RELOC_NUMBER (R_MSP430X_DST_BYTE, 11)
3773
+ RELOC_NUMBER (R_MSP430X_DST, 12)
3774
+ RELOC_NUMBER (R_MSP430X_DST_2ND_BYTE, 13)
3775
+ RELOC_NUMBER (R_MSP430X_DST_2ND, 14)
3776
+ RELOC_NUMBER (R_MSP430X_PCREL_SRC_BYTE, 15)
3777
+ RELOC_NUMBER (R_MSP430X_PCREL_SRC, 16)
3778
+ RELOC_NUMBER (R_MSP430X_PCREL_DST_BYTE, 17)
3779
+ RELOC_NUMBER (R_MSP430X_PCREL_DST, 18)
3780
+ RELOC_NUMBER (R_MSP430X_PCREL_DST_2ND, 19)
3781
+ RELOC_NUMBER (R_MSP430X_PCREL_DST_2ND_BYTE, 20)
3782
+ RELOC_NUMBER (R_MSP430X_S_BYTE, 21)
3783
+ RELOC_NUMBER (R_MSP430X_S, 22)
3784
+ RELOC_NUMBER (R_MSP430X_D_BYTE, 23)
3785
+ RELOC_NUMBER (R_MSP430X_D, 24)
3786
+ RELOC_NUMBER (R_MSP430X_PCREL_D, 25)
3787
+ RELOC_NUMBER (R_MSP430X_INDXD, 26)
3788
+ RELOC_NUMBER (R_MSP430X_PCREL_INDXD, 27)
3790
END_RELOC_NUMBERS (R_MSP430_max)
3792
+/* TODO: Define a set of flags that are appropriate for storage in the e_flags field.
3793
+ * Potential members include:
3794
+ * - Whether CPUX instructions are present
3795
+ * - Whether hardware multiply register references are present (which kind)
3796
+ * - The code addressing mode
3797
+ * - The data addressing mode
3800
+/* Pre-uniarch versions of binutils stored machine types in the
3801
+ * e_flags field, with values up to 471 decimal. Now we store the
3802
+ * machine type in the e_mach field, and use e_flags to identify the
3803
+ * characteristics of the code.
3805
+ * Use the following flag to indicate that this object file uses the
3806
+ * uniarch flag layout. */
3807
+#define EF_MSP430_UNIARCH 0x10000000
3809
+#define EF_MSP430_ARCH_430 0x00000000
3810
+#define EF_MSP430_ARCH_430X 0x00000001
3811
+#define EF_MSP430_ARCH 0x000000FF
3813
+/* These are symbol-associated, not archive-associated, attributes.
3814
+ * Not sure what to do with them. */
3815
+#define EF_MSP430_CPU_430 0x00000000
3816
+#define EF_MSP430_CPU_430X 0x00000200
3817
+#define EF_MSP430_CPU_430XV2 0x00000300
3818
+#define EF_MSP430_CPU 0x00000300
3819
+#define EF_MSP430_MPY_NONE 0x00000000
3820
+#define EF_MSP430_MPY_16 0x00001000
3821
+#define EF_MSP430_MPY_16_SE (0x00008000 + EF_MSP430_MPY_16)
3822
+#define EF_MSP430_MPY_32 0x00002000
3823
+#define EF_MSP430_MPY_32_DW (0x00008000 + EF_MSP430_MPY_32)
3824
+#define EF_MSP430_MPY_CLASS 0x00003000
3825
+#define EF_MSP430_MPY 0x0000F000
3826
+#define EF_MSP430_CODE_NEAR 0x00010000
3827
+#define EF_MSP430_CODE_FAR 0x00020000
3828
+#define EF_MSP430_CODE_MIXED 0x00030000
3829
+#define EF_MSP430_CODE 0x00030000
3830
+#define EF_MSP430_DATA_NEAR 0x00040000
3831
+#define EF_MSP430_DATA_FAR 0x00080000
3832
+#define EF_MSP430_DATA_MIXED 0x000c0000
3833
+#define EF_MSP430_DATA 0x000c0000
3834
+#define EF_MSP430_A20 0x000F0000
3837
#endif /* _ELF_MSP430_H */
3838
diff --git a/include/opcode/msp430.h b/include/opcode/msp430.h
3839
index d3bf130..c281a49 100644
3840
--- a/include/opcode/msp430.h
3841
+++ b/include/opcode/msp430.h
3842
@@ -26,7 +26,7 @@ struct msp430_operand_s
3843
int ol; /* Operand length words. */
3844
int am; /* Addr mode. */
3845
int reg; /* Register. */
3846
- int mode; /* Pperand mode. */
3847
+ int mode; /* Operand mode. */
3850
#ifndef DASM_SECTION
3851
@@ -34,91 +34,252 @@ struct msp430_operand_s
3855
-#define BYTE_OPERATION (1 << 6) /* Byte operation flag for all instructions. */
3856
+#define BYTE_OPERATION (1 << 6) /* Byte operation flag for 430 instructions. */
3857
+#define BYTE_OPERATION_X (1 << 22) /* Byte operation flag for 430x instructions. */
3858
+#define NON_ADDR_OPERATION (1 << 6) /* Address operation flag for 430x instructions. */
3862
+ DEFAULT_OP, // instruction has no modifier
3869
+/** Bit-markers for type of CPU present. */
3870
+typedef enum msp430_cpu_e
3872
+ MSP430_CPU_MSP430 = 0x0000,
3873
+ MSP430_CPU_MSP430X = 0x0002,
3874
+ MSP430_CPU_MSP430XV2 = 0x0003,
3875
+ MSP430_CPU = 0x0003,
3878
+/** Bit-markers for type of hardware multiplier present. */
3879
+typedef enum msp430_mpy_e
3881
+ MSP430_MPY_NONE = 0x0000,
3882
+ MSP430_MPY_16 = 0x0010,
3883
+ MSP430_MPY_16SE = 0x0011,
3884
+ MSP430_MPY_32 = 0x0020,
3885
+ MSP430_MPY_32DW = 0x0022,
3886
+ MSP430_MPY = 0x0030
3892
+ FMT_DOUBLE_OPERAND,
3893
+ FMT_SINGLE_OPERAND,
3895
+ FMT_EMULATED_POLYMORPH_JUMP,
3896
+ FMT_EMULATED_LONG_POLYMORPH_JUMP,
3897
+ FMT_X_DOUBLE_OPERAND,
3898
+ FMT_X_SINGLE_OPERAND,
3903
+ FMT_X = FMT_X_DOUBLE_OPERAND,
3904
+ FMT_MASK = 0x000f,
3906
+ /* allowed modifiers: .b, .w, .a */
3911
+ MOD_MASK = 0x0070,
3913
+ /* opcode variant */
3914
+ VAR_MASK = 0x0380,
3918
+#define OP_V(x) (x << 7)
3920
struct msp430_opcode_s
3928
+ unsigned int insn_opnumb;
3929
+ unsigned int bin_opcode;
3930
+ unsigned int bin_mask;
3933
-#define MSP_INSN(name, size, numb, bin, mask) { #name, size, numb, bin, mask }
3934
+#define opcode_format(opcode) (opcode->fmt & FMT_MASK)
3935
+#define opcode_modifier(opcode) (opcode->fmt & MOD_MASK)
3936
+#define opcode_variant(opcode) ((opcode->fmt & VAR_MASK) >> 7)
3938
+/* opcode variants: */
3941
+ V_NONE = 0, // ordinary instruction
3943
+ /* FMT_EMULATED: */
3944
+ V_NOOP, // no operands: set/clear bit instructions, reti
3945
+ V_SHIFT, // shift instructions
3946
+ V_BR, // br instruction
3948
+ /* FMT_SINGLE_OPERAND: */
3949
+ V_RETI = 1, // reti
3950
+ V_CALL = 2, // hex operand in disassembly
3952
+ /* FMT_X_SINGLE_OPERAND: */
3953
+ // V_NONE - #N operand disallowed
3954
+ V_SWPSXT = 1, // #N operand disallowed, special A/L, B/W bits case with .a modifier
3955
+ V_PUSHX, // #N operand allowed
3957
-static struct msp430_opcode_s msp430_opcodes[] =
3958
+ /* FMT_X_EXCEPTIONS: */
3959
+ V_CALLA = 0, // calla
3960
+ V_ROTM, // two operands, rotations
3961
+ V_POPM, // two operands, popm
3962
+ V_PUSHM, // two operands, pushm
3964
+ /* FMT_X_EMULATED: */
3965
+ // V_NONE - substituted by 430x double operand instruction
3966
+ V_X_SHIFT, // shifts
3967
+ V_RETA, // reta, short instruction, no operands
3968
+ V_EMU_ADDR, // substituted by address instruction other than mova
3969
+ V_BRA, // bra, substituted by mova address instruction == format II exception instruction
3970
+ // clra emulated by msp430 instruction
3972
+ /* FMT_X_ADDRESS: */
3973
+ V_MOVA = 1, // mova, more address modes allowed
3976
+#define MSP_INSN(name, format, opnumb, bin, mask) { #name, format, opnumb, bin, mask }
3978
+static struct msp430_opcode_s const msp430_opcodes[] =
3980
- MSP_INSN (and, 1, 2, 0xf000, 0xf000),
3981
- MSP_INSN (inv, 0, 1, 0xe330, 0xfff0),
3982
- MSP_INSN (xor, 1, 2, 0xe000, 0xf000),
3983
- MSP_INSN (setz, 0, 0, 0xd322, 0xffff),
3984
- MSP_INSN (setc, 0, 0, 0xd312, 0xffff),
3985
- MSP_INSN (eint, 0, 0, 0xd232, 0xffff),
3986
- MSP_INSN (setn, 0, 0, 0xd222, 0xffff),
3987
- MSP_INSN (bis, 1, 2, 0xd000, 0xf000),
3988
- MSP_INSN (clrz, 0, 0, 0xc322, 0xffff),
3989
- MSP_INSN (clrc, 0, 0, 0xc312, 0xffff),
3990
- MSP_INSN (dint, 0, 0, 0xc232, 0xffff),
3991
- MSP_INSN (clrn, 0, 0, 0xc222, 0xffff),
3992
- MSP_INSN (bic, 1, 2, 0xc000, 0xf000),
3993
- MSP_INSN (bit, 1, 2, 0xb000, 0xf000),
3994
- MSP_INSN (dadc, 0, 1, 0xa300, 0xff30),
3995
- MSP_INSN (dadd, 1, 2, 0xa000, 0xf000),
3996
- MSP_INSN (tst, 0, 1, 0x9300, 0xff30),
3997
- MSP_INSN (cmp, 1, 2, 0x9000, 0xf000),
3998
- MSP_INSN (decd, 0, 1, 0x8320, 0xff30),
3999
- MSP_INSN (dec, 0, 1, 0x8310, 0xff30),
4000
- MSP_INSN (sub, 1, 2, 0x8000, 0xf000),
4001
- MSP_INSN (sbc, 0, 1, 0x7300, 0xff30),
4002
- MSP_INSN (subc, 1, 2, 0x7000, 0xf000),
4003
- MSP_INSN (adc, 0, 1, 0x6300, 0xff30),
4004
- MSP_INSN (rlc, 0, 2, 0x6000, 0xf000),
4005
- MSP_INSN (addc, 1, 2, 0x6000, 0xf000),
4006
- MSP_INSN (incd, 0, 1, 0x5320, 0xff30),
4007
- MSP_INSN (inc, 0, 1, 0x5310, 0xff30),
4008
- MSP_INSN (rla, 0, 2, 0x5000, 0xf000),
4009
- MSP_INSN (add, 1, 2, 0x5000, 0xf000),
4010
- MSP_INSN (nop, 0, 0, 0x4303, 0xffff),
4011
- MSP_INSN (clr, 0, 1, 0x4300, 0xff30),
4012
- MSP_INSN (ret, 0, 0, 0x4130, 0xff30),
4013
- MSP_INSN (pop, 0, 1, 0x4130, 0xff30),
4014
- MSP_INSN (br, 0, 3, 0x4000, 0xf000),
4015
- MSP_INSN (mov, 1, 2, 0x4000, 0xf000),
4016
- MSP_INSN (jmp, 3, 1, 0x3c00, 0xfc00),
4017
- MSP_INSN (jl, 3, 1, 0x3800, 0xfc00),
4018
- MSP_INSN (jge, 3, 1, 0x3400, 0xfc00),
4019
- MSP_INSN (jn, 3, 1, 0x3000, 0xfc00),
4020
- MSP_INSN (jc, 3, 1, 0x2c00, 0xfc00),
4021
- MSP_INSN (jhs, 3, 1, 0x2c00, 0xfc00),
4022
- MSP_INSN (jnc, 3, 1, 0x2800, 0xfc00),
4023
- MSP_INSN (jlo, 3, 1, 0x2800, 0xfc00),
4024
- MSP_INSN (jz, 3, 1, 0x2400, 0xfc00),
4025
- MSP_INSN (jeq, 3, 1, 0x2400, 0xfc00),
4026
- MSP_INSN (jnz, 3, 1, 0x2000, 0xfc00),
4027
- MSP_INSN (jne, 3, 1, 0x2000, 0xfc00),
4028
- MSP_INSN (reti, 2, 0, 0x1300, 0xffc0),
4029
- MSP_INSN (call, 2, 1, 0x1280, 0xffc0),
4030
- MSP_INSN (push, 2, 1, 0x1200, 0xff80),
4031
- MSP_INSN (sxt, 2, 1, 0x1180, 0xffc0),
4032
- MSP_INSN (rra, 2, 1, 0x1100, 0xff80),
4033
- MSP_INSN (swpb, 2, 1, 0x1080, 0xffc0),
4034
- MSP_INSN (rrc, 2, 1, 0x1000, 0xff80),
4035
+ MSP_INSN (and, FMT_DOUBLE_OPERAND | MOD_W|MOD_B | OP_V(0), 2, 0xf000, 0xfffff000),
4036
+ MSP_INSN (inv, FMT_EMULATED | MOD_W|MOD_B | OP_V(0), 1, 0xe330, 0xfffffff0),
4037
+ MSP_INSN (xor, FMT_DOUBLE_OPERAND | MOD_W|MOD_B | OP_V(0), 2, 0xe000, 0xfffff000),
4038
+ MSP_INSN (setz, FMT_EMULATED | MOD_NONE | OP_V(V_NOOP), 0, 0xd322, 0xffffffff),
4039
+ MSP_INSN (setc, FMT_EMULATED | MOD_NONE | OP_V(V_NOOP), 0, 0xd312, 0xffffffff),
4040
+ MSP_INSN (eint, FMT_EMULATED | MOD_NONE | OP_V(V_NOOP), 0, 0xd232, 0xffffffff),
4041
+ MSP_INSN (setn, FMT_EMULATED | MOD_NONE | OP_V(V_NOOP), 0, 0xd222, 0xffffffff),
4042
+ MSP_INSN (bis, FMT_DOUBLE_OPERAND | MOD_W|MOD_B | OP_V(0), 2, 0xd000, 0xfffff000),
4043
+ MSP_INSN (clrz, FMT_EMULATED | MOD_NONE | OP_V(V_NOOP), 0, 0xc322, 0xffffffff),
4044
+ MSP_INSN (clrc, FMT_EMULATED | MOD_NONE | OP_V(V_NOOP), 0, 0xc312, 0xffffffff),
4045
+ MSP_INSN (dint, FMT_EMULATED | MOD_NONE | OP_V(V_NOOP), 0, 0xc232, 0xffffffff),
4046
+ MSP_INSN (clrn, FMT_EMULATED | MOD_NONE | OP_V(V_NOOP), 0, 0xc222, 0xffffffff),
4047
+ MSP_INSN (bic, FMT_DOUBLE_OPERAND | MOD_W|MOD_B | OP_V(0), 2, 0xc000, 0xfffff000),
4048
+ MSP_INSN (bit, FMT_DOUBLE_OPERAND | MOD_W|MOD_B | OP_V(0), 2, 0xb000, 0xfffff000),
4049
+ MSP_INSN (dadc, FMT_EMULATED | MOD_W|MOD_B | OP_V(0), 1, 0xa300, 0xffffff30),
4050
+ MSP_INSN (dadd, FMT_DOUBLE_OPERAND | MOD_W|MOD_B | OP_V(0), 2, 0xa000, 0xfffff000),
4051
+ MSP_INSN (tst, FMT_EMULATED | MOD_W|MOD_B | OP_V(0), 1, 0x9300, 0xffffff30),
4052
+ MSP_INSN (cmp, FMT_DOUBLE_OPERAND | MOD_W|MOD_B | OP_V(0), 2, 0x9000, 0xfffff000),
4053
+ MSP_INSN (decd, FMT_EMULATED | MOD_W|MOD_B | OP_V(0), 1, 0x8320, 0xffffff30),
4054
+ MSP_INSN (dec, FMT_EMULATED | MOD_W|MOD_B | OP_V(0), 1, 0x8310, 0xffffff30),
4055
+ MSP_INSN (sub, FMT_DOUBLE_OPERAND | MOD_W|MOD_B | OP_V(0), 2, 0x8000, 0xfffff000),
4056
+ MSP_INSN (sbc, FMT_EMULATED | MOD_W|MOD_B | OP_V(0), 1, 0x7300, 0xffffff30),
4057
+ MSP_INSN (subc, FMT_DOUBLE_OPERAND | MOD_W|MOD_B | OP_V(0), 2, 0x7000, 0xfffff000),
4058
+ MSP_INSN (adc, FMT_EMULATED | MOD_W|MOD_B | OP_V(0), 1, 0x6300, 0xffffff30),
4059
+ MSP_INSN (rlc, FMT_EMULATED | MOD_W|MOD_B | OP_V(V_SHIFT), 2, 0x6000, 0xfffff000),
4060
+ MSP_INSN (addc, FMT_DOUBLE_OPERAND | MOD_W|MOD_B | OP_V(0), 2, 0x6000, 0xfffff000),
4061
+ MSP_INSN (incd, FMT_EMULATED | MOD_W|MOD_B | OP_V(0), 1, 0x5320, 0xffffff30),
4062
+ MSP_INSN (inc, FMT_EMULATED | MOD_W|MOD_B | OP_V(0), 1, 0x5310, 0xffffff30),
4063
+ MSP_INSN (rla, FMT_EMULATED | MOD_W|MOD_B | OP_V(V_SHIFT), 2, 0x5000, 0xfffff000),
4064
+ MSP_INSN (add, FMT_DOUBLE_OPERAND | MOD_W|MOD_B | OP_V(0), 2, 0x5000, 0xfffff000),
4065
+ MSP_INSN (nop, FMT_EMULATED | MOD_NONE | OP_V(V_NOOP), 0, 0x4303, 0xffffffff),
4066
+ MSP_INSN (clr, FMT_EMULATED | MOD_W|MOD_B | OP_V(0), 1, 0x4300, 0xffffff30),
4067
+ MSP_INSN (clra, FMT_EMULATED | MOD_NONE | OP_V(0), 1, 0x4300, 0xffffff30), // MOV #0, Rdst
4068
+ MSP_INSN (ret, FMT_EMULATED | MOD_NONE | OP_V(V_NOOP), 0, 0x4130, 0xffffffff),
4069
+ MSP_INSN (pop, FMT_EMULATED | MOD_W|MOD_B | OP_V(0), 1, 0x4130, 0xffffff30),
4070
+ MSP_INSN (br, FMT_EMULATED | MOD_NONE | OP_V(V_BR), 1, 0x4000, 0xfffff08f),
4071
+ MSP_INSN (mov, FMT_DOUBLE_OPERAND | MOD_W|MOD_B | OP_V(0), 2, 0x4000, 0xfffff000),
4073
+ MSP_INSN (jmp, FMT_JUMP | MOD_NONE | OP_V(0), 1, 0x3c00, 0xfffffc00),
4074
+ MSP_INSN (jl, FMT_JUMP | MOD_NONE | OP_V(0), 1, 0x3800, 0xfffffc00),
4075
+ MSP_INSN (jge, FMT_JUMP | MOD_NONE | OP_V(0), 1, 0x3400, 0xfffffc00),
4076
+ MSP_INSN (jn, FMT_JUMP | MOD_NONE | OP_V(0), 1, 0x3000, 0xfffffc00),
4077
+ MSP_INSN (jc, FMT_JUMP | MOD_NONE | OP_V(0), 1, 0x2c00, 0xfffffc00),
4078
+ MSP_INSN (jhs, FMT_JUMP | MOD_NONE | OP_V(0), 1, 0x2c00, 0xfffffc00),
4079
+ MSP_INSN (jnc, FMT_JUMP | MOD_NONE | OP_V(0), 1, 0x2800, 0xfffffc00),
4080
+ MSP_INSN (jlo, FMT_JUMP | MOD_NONE | OP_V(0), 1, 0x2800, 0xfffffc00),
4081
+ MSP_INSN (jz, FMT_JUMP | MOD_NONE | OP_V(0), 1, 0x2400, 0xfffffc00),
4082
+ MSP_INSN (jeq, FMT_JUMP | MOD_NONE | OP_V(0), 1, 0x2400, 0xfffffc00),
4083
+ MSP_INSN (jnz, FMT_JUMP | MOD_NONE | OP_V(0), 1, 0x2000, 0xfffffc00),
4084
+ MSP_INSN (jne, FMT_JUMP | MOD_NONE | OP_V(0), 1, 0x2000, 0xfffffc00),
4086
+ MSP_INSN (reti, FMT_SINGLE_OPERAND | MOD_NONE | OP_V(V_RETI), 0, 0x1300, 0xffffffc0),
4087
+ MSP_INSN (call, FMT_SINGLE_OPERAND | MOD_NONE | OP_V(V_CALL), 1, 0x1280, 0xffffffc0),
4088
+ MSP_INSN (push, FMT_SINGLE_OPERAND | MOD_W|MOD_B | OP_V(0), 1, 0x1200, 0xffffff80),
4089
+ MSP_INSN (sxt, FMT_SINGLE_OPERAND | MOD_NONE | OP_V(0), 1, 0x1180, 0xffffffc0),
4090
+ MSP_INSN (rra, FMT_SINGLE_OPERAND | MOD_W|MOD_B | OP_V(0), 1, 0x1100, 0xffffff80),
4091
+ MSP_INSN (swpb, FMT_SINGLE_OPERAND | MOD_NONE | OP_V(0), 1, 0x1080, 0xffffffc0),
4092
+ MSP_INSN (rrc, FMT_SINGLE_OPERAND | MOD_W|MOD_B | OP_V(0), 1, 0x1000, 0xffffff80),
4095
+ /* emulated instructions placed just before instruction emulated by for disassembly search */
4096
+ MSP_INSN (popx, FMT_X_EMULATED | MOD_W|MOD_B|MOD_A | OP_V(0), 1, 0x41301800, 0xff30f800), // MOVX @SP+, dst
4097
+ MSP_INSN (clrx, FMT_X_EMULATED | MOD_W|MOD_B|MOD_A | OP_V(0), 1, 0x43001800, 0xff30f800), // MOVX #0, dst
4098
+ MSP_INSN (movx, FMT_X_DOUBLE_OPERAND | MOD_W|MOD_B|MOD_A | OP_V(0), 2, 0x40001800, 0xf000f800),
4099
+ MSP_INSN (incx, FMT_X_EMULATED | MOD_W|MOD_B|MOD_A | OP_V(0), 1, 0x53101800, 0xff30f800), // ADDX #1, dst
4100
+ MSP_INSN (incdx, FMT_X_EMULATED | MOD_W|MOD_B|MOD_A | OP_V(0), 1, 0x53201800, 0xff30f800), // ADDX #2, dst
4101
+ MSP_INSN (rlax, FMT_X_EMULATED | MOD_W|MOD_B|MOD_A | OP_V(V_X_SHIFT), 1, 0x50001800, 0xf000f800), // ADDX dst, dst
4102
+ MSP_INSN (addx, FMT_X_DOUBLE_OPERAND | MOD_W|MOD_B|MOD_A | OP_V(0), 2, 0x50001800, 0xf000f800),
4103
+ MSP_INSN (adcx, FMT_X_EMULATED | MOD_W|MOD_B|MOD_A | OP_V(0), 1, 0x63001800, 0xff30f800), // ADDCX #0, dst
4104
+ MSP_INSN (rlcx, FMT_X_EMULATED | MOD_W|MOD_B|MOD_A | OP_V(V_X_SHIFT), 1, 0x60001800, 0xf000f800), // ADDCX dst, dst
4105
+ MSP_INSN (addcx, FMT_X_DOUBLE_OPERAND | MOD_W|MOD_B|MOD_A | OP_V(0), 2, 0x60001800, 0xf000f800),
4106
+ MSP_INSN (sbcx, FMT_X_EMULATED | MOD_W|MOD_B|MOD_A | OP_V(0), 1, 0x73001800, 0xff30f800), // SUBCX #0, dst
4107
+ MSP_INSN (subcx, FMT_X_DOUBLE_OPERAND | MOD_W|MOD_B|MOD_A | OP_V(0), 2, 0x70001800, 0xf000f800),
4108
+ MSP_INSN (decx, FMT_X_EMULATED | MOD_W|MOD_B|MOD_A | OP_V(0), 1, 0x83101800, 0xff30f800), // SUBX #1, dst
4109
+ MSP_INSN (decdx, FMT_X_EMULATED | MOD_W|MOD_B|MOD_A | OP_V(0), 1, 0x83201800, 0xff30f800), // SUBX #2, dst
4110
+ MSP_INSN (subx, FMT_X_DOUBLE_OPERAND | MOD_W|MOD_B|MOD_A | OP_V(0), 2, 0x80001800, 0xf000f800),
4111
+ MSP_INSN (tstx, FMT_X_EMULATED | MOD_W|MOD_B|MOD_A | OP_V(0), 1, 0x93001800, 0xff30f800), // CMPX #0, dst
4112
+ MSP_INSN (cmpx, FMT_X_DOUBLE_OPERAND | MOD_W|MOD_B|MOD_A | OP_V(0), 2, 0x90001800, 0xf000f800),
4113
+ MSP_INSN (dadcx, FMT_X_EMULATED | MOD_W|MOD_B|MOD_A | OP_V(0), 1, 0xa3001800, 0xff30f800), // DADDX #0, dst
4114
+ MSP_INSN (daddx, FMT_X_DOUBLE_OPERAND | MOD_W|MOD_B|MOD_A | OP_V(0), 2, 0xa0001800, 0xf000f800),
4115
+ MSP_INSN (bitx, FMT_X_DOUBLE_OPERAND | MOD_W|MOD_B|MOD_A | OP_V(0), 2, 0xb0001800, 0xf000f800),
4116
+ MSP_INSN (bicx, FMT_X_DOUBLE_OPERAND | MOD_W|MOD_B|MOD_A | OP_V(0), 2, 0xc0001800, 0xf000f800),
4117
+ MSP_INSN (bisx, FMT_X_DOUBLE_OPERAND | MOD_W|MOD_B|MOD_A | OP_V(0), 2, 0xd0001800, 0xf000f800),
4118
+ MSP_INSN (invx, FMT_X_EMULATED | MOD_W|MOD_B|MOD_A | OP_V(0), 1, 0xe3301800, 0xff30f800), // XORX #-1, dst
4119
+ MSP_INSN (xorx, FMT_X_DOUBLE_OPERAND | MOD_W|MOD_B|MOD_A | OP_V(0), 2, 0xe0001800, 0xf000f800),
4120
+ MSP_INSN (andx, FMT_X_DOUBLE_OPERAND | MOD_W|MOD_B|MOD_A | OP_V(0), 2, 0xf0001800, 0xf000f800),
4122
+ MSP_INSN (rrcx, FMT_X_SINGLE_OPERAND | MOD_W|MOD_B|MOD_A | OP_V(0), 1, 0x10001800, 0xff80f800),
4123
+ MSP_INSN (swpbx, FMT_X_SINGLE_OPERAND | MOD_W|MOD_A | OP_V(V_SWPSXT), 1, 0x10801800, 0xffc0f800),
4124
+ MSP_INSN (rrax, FMT_X_SINGLE_OPERAND | MOD_W|MOD_B|MOD_A | OP_V(0), 1, 0x11001800, 0xff80f800),
4125
+ MSP_INSN (sxtx, FMT_X_SINGLE_OPERAND | MOD_W|MOD_A | OP_V(V_SWPSXT), 1, 0x11801800, 0xffc0f800),
4126
+ MSP_INSN (pushx, FMT_X_SINGLE_OPERAND | MOD_W|MOD_B|MOD_A | OP_V(V_PUSHX), 1, 0x12001800, 0xff80f800),
4128
+ MSP_INSN (calla, FMT_X_EXCEPTION | MOD_NONE | OP_V(V_CALLA), 1, 0x1300, 0xffffff00),
4129
+ MSP_INSN (pushm, FMT_X_EXCEPTION | MOD_W|MOD_A | OP_V(V_PUSHM), 2, 0x1400, 0xfffffe00),
4130
+ MSP_INSN (popm, FMT_X_EXCEPTION | MOD_W|MOD_A | OP_V(V_POPM), 2, 0x1600, 0xfffffe00),
4131
+ MSP_INSN (rrcm, FMT_X_EXCEPTION | MOD_W|MOD_A | OP_V(V_ROTM), 2, 0x0040, 0xfffff3e0),
4132
+ MSP_INSN (rram, FMT_X_EXCEPTION | MOD_W|MOD_A | OP_V(V_ROTM), 2, 0x0140, 0xfffff3e0),
4133
+ MSP_INSN (rlam, FMT_X_EXCEPTION | MOD_W|MOD_A | OP_V(V_ROTM), 2, 0x0240, 0xfffff3e0),
4134
+ MSP_INSN (rrum, FMT_X_EXCEPTION | MOD_W|MOD_A | OP_V(V_ROTM), 2, 0x0340, 0xfffff3e0),
4137
+ MSP_INSN (incda, FMT_X_EMULATED | MOD_NONE | OP_V(V_EMU_ADDR), 1, 0x03e0, 0xfffffff0), // ADDA #2, Rdst = ADDA R3, Rdst
4138
+ MSP_INSN (adda, FMT_X_ADDRESS | MOD_NONE | OP_V(0), 2, 0x00a0, 0xfffff0b0),
4139
+ MSP_INSN (tsta, FMT_X_EMULATED | MOD_NONE | OP_V(V_EMU_ADDR), 1, 0x03d0, 0xfffffff0), // CMPA #0, Rdst = CMPA R3, Rdst
4140
+ MSP_INSN (cmpa, FMT_X_ADDRESS | MOD_NONE | OP_V(0), 2, 0x0090, 0xfffff0b0),
4141
+ MSP_INSN (decda, FMT_X_EMULATED | MOD_NONE | OP_V(V_EMU_ADDR), 1, 0x03f0, 0xfffffff0), // SUBA #2, Rdst = SUBA R3, Rdst
4142
+ MSP_INSN (suba, FMT_X_ADDRESS | MOD_NONE | OP_V(0), 2, 0x00b0, 0xfffff0b0),
4143
+ MSP_INSN (reta, FMT_X_EMULATED | MOD_NONE | OP_V(V_RETA), 0, 0x0110, 0xffffffff), // MOVA @SP+, PC
4144
+ MSP_INSN (bra, FMT_X_EMULATED | MOD_NONE | OP_V(V_BRA), 1, 0x0000, 0xfffff0cf), // MOVA dst, PC
4145
+ MSP_INSN (bra, FMT_X_EMULATED | MOD_NONE | OP_V(V_BRA), 1, 0x0080, 0xfffff0bf), // MOVA #imm20, PC; MOVA Rsrc, Rdst
4146
+ MSP_INSN (mova, FMT_X_ADDRESS | MOD_NONE | OP_V(V_MOVA), 1, 0x0000, 0xfffff000),
4148
/* Simple polymorphs. */
4149
- MSP_INSN (beq, 4, 0, 0, 0xffff),
4150
- MSP_INSN (bne, 4, 1, 0, 0xffff),
4151
- MSP_INSN (blt, 4, 2, 0, 0xffff),
4152
- MSP_INSN (bltu, 4, 3, 0, 0xffff),
4153
- MSP_INSN (bge, 4, 4, 0, 0xffff),
4154
- MSP_INSN (bgeu, 4, 5, 0, 0xffff),
4155
- MSP_INSN (bltn, 4, 6, 0, 0xffff),
4156
- MSP_INSN (jump, 4, 7, 0, 0xffff),
4157
- /* Long polymorphs. */
4158
- MSP_INSN (bgt, 5, 0, 0, 0xffff),
4159
- MSP_INSN (bgtu, 5, 1, 0, 0xffff),
4160
- MSP_INSN (bleu, 5, 2, 0, 0xffff),
4161
- MSP_INSN (ble, 5, 3, 0, 0xffff),
4162
+ MSP_INSN (beq, FMT_EMULATED_POLYMORPH_JUMP | MOD_NONE | OP_V(0), 1, 0, 0xffff),
4163
+ MSP_INSN (bne, FMT_EMULATED_POLYMORPH_JUMP | MOD_NONE | OP_V(1), 1, 0, 0xffff),
4164
+ MSP_INSN (blt, FMT_EMULATED_POLYMORPH_JUMP | MOD_NONE | OP_V(2), 1, 0, 0xffff),
4165
+ MSP_INSN (bltu, FMT_EMULATED_POLYMORPH_JUMP | MOD_NONE | OP_V(3), 1, 0, 0xffff),
4166
+ MSP_INSN (bge, FMT_EMULATED_POLYMORPH_JUMP | MOD_NONE | OP_V(4), 1, 0, 0xffff),
4167
+ MSP_INSN (bgeu, FMT_EMULATED_POLYMORPH_JUMP | MOD_NONE | OP_V(5), 1, 0, 0xffff),
4168
+ MSP_INSN (bltn, FMT_EMULATED_POLYMORPH_JUMP | MOD_NONE | OP_V(6), 1, 0, 0xffff),
4169
+ MSP_INSN (jump, FMT_EMULATED_POLYMORPH_JUMP | MOD_NONE | OP_V(7), 1, 0, 0xffff),
4171
+ /* Long polymorphs. */
4172
+ MSP_INSN (bgt, FMT_EMULATED_LONG_POLYMORPH_JUMP | MOD_NONE | OP_V(0), 1, 0, 0xffff),
4173
+ MSP_INSN (bgtu, FMT_EMULATED_LONG_POLYMORPH_JUMP | MOD_NONE | OP_V(1), 1, 0, 0xffff),
4174
+ MSP_INSN (bleu, FMT_EMULATED_LONG_POLYMORPH_JUMP | MOD_NONE | OP_V(2), 1, 0, 0xffff),
4175
+ MSP_INSN (ble, FMT_EMULATED_LONG_POLYMORPH_JUMP | MOD_NONE | OP_V(3), 1, 0, 0xffff),
4176
/* End of instruction set. */
4177
{ NULL, 0, 0, 0, 0 }
4179
diff --git a/ld/Makefile.am b/ld/Makefile.am
4180
index b392e14..f3c0130 100644
4181
--- a/ld/Makefile.am
4182
+++ b/ld/Makefile.am
4183
@@ -328,65 +328,7 @@ ALL_EMULATION_SOURCES = \
4250
@@ -1396,242 +1338,10 @@ emn10300.c: $(srcdir)/emulparams/mn10300.sh \
4251
$(srcdir)/emulparams/mn10200.sh \
4252
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
4253
${GENSCRIPTS} mn10300 "$(tdir_mn10300)"
4254
-emsp430x110.c: $(srcdir)/emulparams/msp430all.sh \
4255
+emsp430.c: $(srcdir)/emulparams/msp430uni.sh \
4256
$(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4258
- ${GENSCRIPTS} msp430x110 "$(tdir_msp430x110)" msp430all
4259
-emsp430x1101.c: $(srcdir)/emulparams/msp430all.sh \
4260
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4262
- ${GENSCRIPTS} msp430x1101 "$(tdir_msp430x1101)" msp430all
4263
-emsp430x1111.c: $(srcdir)/emulparams/msp430all.sh \
4264
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4266
- ${GENSCRIPTS} msp430x1111 "$(tdir_msp430x1111)" msp430all
4267
-emsp430x112.c: $(srcdir)/emulparams/msp430all.sh \
4268
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4270
- ${GENSCRIPTS} msp430x112 "$(tdir_msp430x112)" msp430all
4271
-emsp430x1121.c: $(srcdir)/emulparams/msp430all.sh \
4272
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4274
- ${GENSCRIPTS} msp430x1121 "$(tdir_msp430x1121)" msp430all
4275
-emsp430x1122.c: $(srcdir)/emulparams/msp430all.sh \
4276
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4278
- ${GENSCRIPTS} msp430x1122 "$(tdir_msp430x1122)" msp430all
4279
-emsp430x1132.c: $(srcdir)/emulparams/msp430all.sh \
4280
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4282
- ${GENSCRIPTS} msp430x1132 "$(tdir_msp430x1132)" msp430all
4283
-emsp430x122.c: $(srcdir)/emulparams/msp430all.sh \
4284
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4286
- ${GENSCRIPTS} msp430x122 "$(tdir_msp430x122)" msp430all
4287
-emsp430x1222.c: $(srcdir)/emulparams/msp430all.sh \
4288
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4290
- ${GENSCRIPTS} msp430x1222 "$(tdir_msp430x1222)" msp430all
4291
-emsp430x123.c: $(srcdir)/emulparams/msp430all.sh \
4292
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4294
- ${GENSCRIPTS} msp430x123 "$(tdir_msp430x123)" msp430all
4295
-emsp430x1232.c: $(srcdir)/emulparams/msp430all.sh \
4296
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4298
- ${GENSCRIPTS} msp430x1232 "$(tdir_msp430x1232)" msp430all
4299
-emsp430x133.c: $(srcdir)/emulparams/msp430all.sh \
4300
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4302
- ${GENSCRIPTS} msp430x133 "$(tdir_msp430x133)" msp430all
4303
-emsp430x1331.c: $(srcdir)/emulparams/msp430all.sh \
4304
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4306
- ${GENSCRIPTS} msp430x1331 "$(tdir_msp430x1331)" msp430all
4307
-emsp430x135.c: $(srcdir)/emulparams/msp430all.sh \
4308
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4310
- ${GENSCRIPTS} msp430x135 "$(tdir_msp430x135)" msp430all
4311
-emsp430x1351.c: $(srcdir)/emulparams/msp430all.sh \
4312
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4314
- ${GENSCRIPTS} msp430x1351 "$(tdir_msp430x1351)" msp430all
4315
-emsp430x147.c: $(srcdir)/emulparams/msp430all.sh \
4316
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4318
- ${GENSCRIPTS} msp430x147 "$(tdir_msp430x147)" msp430all
4319
-emsp430x148.c: $(srcdir)/emulparams/msp430all.sh \
4320
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4322
- ${GENSCRIPTS} msp430x148 "$(tdir_msp430x148)" msp430all
4323
-emsp430x149.c: $(srcdir)/emulparams/msp430all.sh \
4324
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4326
- ${GENSCRIPTS} msp430x149 "$(tdir_msp430x149)" msp430all
4327
-emsp430x155.c: $(srcdir)/emulparams/msp430all.sh \
4328
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4330
- ${GENSCRIPTS} msp430x155 "$(tdir_msp430x155)" msp430all
4331
-emsp430x156.c: $(srcdir)/emulparams/msp430all.sh \
4332
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4334
- ${GENSCRIPTS} msp430x156 "$(tdir_msp430x156)" msp430all
4335
-emsp430x157.c: $(srcdir)/emulparams/msp430all.sh \
4336
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4338
- ${GENSCRIPTS} msp430x157 "$(tdir_msp430x157)" msp430all
4339
-emsp430x1610.c: $(srcdir)/emulparams/msp430all.sh \
4340
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4342
- ${GENSCRIPTS} msp430x1610 "$(tdir_msp430x1610)" msp430all
4343
-emsp430x1611.c: $(srcdir)/emulparams/msp430all.sh \
4344
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4346
- ${GENSCRIPTS} msp430x1611 "$(tdir_msp430x1611)" msp430all
4347
-emsp430x1612.c: $(srcdir)/emulparams/msp430all.sh \
4348
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4350
- ${GENSCRIPTS} msp430x1612 "$(tdir_msp430x1612)" msp430all
4351
-emsp430x167.c: $(srcdir)/emulparams/msp430all.sh \
4352
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4354
- ${GENSCRIPTS} msp430x167 "$(tdir_msp430x167)" msp430all
4355
-emsp430x168.c: $(srcdir)/emulparams/msp430all.sh \
4356
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4358
- ${GENSCRIPTS} msp430x168 "$(tdir_msp430x168)" msp430all
4359
-emsp430x169.c: $(srcdir)/emulparams/msp430all.sh \
4360
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4362
- ${GENSCRIPTS} msp430x169 "$(tdir_msp430x169)" msp430all
4363
-emsp430x2101.c: $(srcdir)/emulparams/msp430all.sh \
4364
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4366
- ${GENSCRIPTS} msp430x2101 "$(tdir_msp430x2101)" msp430all
4367
-emsp430x2111.c: $(srcdir)/emulparams/msp430all.sh \
4368
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4370
- ${GENSCRIPTS} msp430x2111 "$(tdir_msp430x2111)" msp430all
4371
-emsp430x2121.c: $(srcdir)/emulparams/msp430all.sh \
4372
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4374
- ${GENSCRIPTS} msp430x2121 "$(tdir_msp430x2121)" msp430all
4375
-emsp430x2131.c: $(srcdir)/emulparams/msp430all.sh \
4376
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4378
- ${GENSCRIPTS} msp430x2131 "$(tdir_msp430x2131)" msp430all
4379
-emsp430x311.c: $(srcdir)/emulparams/msp430all.sh \
4380
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \
4382
- ${GENSCRIPTS} msp430x311 "$(tdir_msp430x311)" msp430all
4383
-emsp430x312.c: $(srcdir)/emulparams/msp430all.sh \
4384
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \
4386
- ${GENSCRIPTS} msp430x312 "$(tdir_msp430x312)" msp430all
4387
-emsp430x313.c: $(srcdir)/emulparams/msp430all.sh \
4388
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \
4390
- ${GENSCRIPTS} msp430x313 "$(tdir_msp430x313)" msp430all
4391
-emsp430x314.c: $(srcdir)/emulparams/msp430all.sh \
4392
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \
4394
- ${GENSCRIPTS} msp430x314 "$(tdir_msp430x314)" msp430all
4395
-emsp430x315.c: $(srcdir)/emulparams/msp430all.sh \
4396
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \
4398
- ${GENSCRIPTS} msp430x315 "$(tdir_msp430x315)" msp430all
4399
-emsp430x323.c: $(srcdir)/emulparams/msp430all.sh \
4400
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \
4402
- ${GENSCRIPTS} msp430x323 "$(tdir_msp430x323)" msp430all
4403
-emsp430x325.c: $(srcdir)/emulparams/msp430all.sh \
4404
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \
4406
- ${GENSCRIPTS} msp430x325 "$(tdir_msp430x325)" msp430all
4407
-emsp430x336.c: $(srcdir)/emulparams/msp430all.sh \
4408
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \
4410
- ${GENSCRIPTS} msp430x336 "$(tdir_msp430x336)" msp430all
4411
-emsp430x337.c: $(srcdir)/emulparams/msp430all.sh \
4412
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \
4414
- ${GENSCRIPTS} msp430x337 "$(tdir_msp430x337)" msp430all
4415
-emsp430x412.c: $(srcdir)/emulparams/msp430all.sh \
4416
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4418
- ${GENSCRIPTS} msp430x412 "$(tdir_msp430x412)" msp430all
4419
-emsp430x413.c: $(srcdir)/emulparams/msp430all.sh \
4420
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4422
- ${GENSCRIPTS} msp430x413 "$(tdir_msp430x413)" msp430all
4423
-emsp430x415.c: $(srcdir)/emulparams/msp430all.sh \
4424
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4426
- ${GENSCRIPTS} msp430x415 "$(tdir_msp430x415)" msp430all
4427
-emsp430x417.c: $(srcdir)/emulparams/msp430all.sh \
4428
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4430
- ${GENSCRIPTS} msp430x417 "$(tdir_msp430x417)" msp430all
4431
-emsp430x435.c: $(srcdir)/emulparams/msp430all.sh \
4432
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4434
- ${GENSCRIPTS} msp430x435 "$(tdir_msp430x435)" msp430all
4435
-emsp430x436.c: $(srcdir)/emulparams/msp430all.sh \
4436
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4438
- ${GENSCRIPTS} msp430x436 "$(tdir_msp430x436)" msp430all
4439
-emsp430x437.c: $(srcdir)/emulparams/msp430all.sh \
4440
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4442
- ${GENSCRIPTS} msp430x437 "$(tdir_msp430x437)" msp430all
4443
-emsp430x447.c: $(srcdir)/emulparams/msp430all.sh \
4444
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4446
- ${GENSCRIPTS} msp430x447 "$(tdir_msp430x447)" msp430all
4447
-emsp430x448.c: $(srcdir)/emulparams/msp430all.sh \
4448
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4450
- ${GENSCRIPTS} msp430x448 "$(tdir_msp430x448)" msp430all
4451
-emsp430x449.c: $(srcdir)/emulparams/msp430all.sh \
4452
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4454
- ${GENSCRIPTS} msp430x449 "$(tdir_msp430x449)" msp430all
4455
-emsp430xE423.c: $(srcdir)/emulparams/msp430all.sh \
4456
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4458
- ${GENSCRIPTS} msp430xE423 "$(tdir_msp430xE423)" msp430all
4459
-emsp430xE425.c: $(srcdir)/emulparams/msp430all.sh \
4460
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4462
- ${GENSCRIPTS} msp430xE425 "$(tdir_msp430xE425)" msp430all
4463
-emsp430xE427.c: $(srcdir)/emulparams/msp430all.sh \
4464
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4466
- ${GENSCRIPTS} msp430xE427 "$(tdir_msp430xE427)" msp430all
4467
-emsp430xG437.c: $(srcdir)/emulparams/msp430all.sh \
4468
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4470
- ${GENSCRIPTS} msp430xG437 "$(tdir_msp430xG437)" msp430all
4471
-emsp430xG438.c: $(srcdir)/emulparams/msp430all.sh \
4472
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4474
- ${GENSCRIPTS} msp430xG438 "$(tdir_msp430xG438)" msp430all
4475
-emsp430xG439.c: $(srcdir)/emulparams/msp430all.sh \
4476
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4478
- ${GENSCRIPTS} msp430xG439 "$(tdir_msp430xG439)" msp430all
4479
-emsp430xW423.c: $(srcdir)/emulparams/msp430all.sh \
4480
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4482
- ${GENSCRIPTS} msp430xW423 "$(tdir_msp430xW423)" msp430all
4483
-emsp430xW425.c: $(srcdir)/emulparams/msp430all.sh \
4484
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4486
- ${GENSCRIPTS} msp430xW425 "$(tdir_msp430xW425)" msp430all
4487
-emsp430xW427.c: $(srcdir)/emulparams/msp430all.sh \
4488
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4490
- ${GENSCRIPTS} msp430xW427 "$(tdir_msp430xW427)" msp430all
4491
+ ${GENSCRIPTS} msp430 "$(tdir_msp430)" msp430uni
4492
enews.c: $(srcdir)/emulparams/news.sh \
4493
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
4494
${GENSCRIPTS} news "$(tdir_news)"
4495
diff --git a/ld/Makefile.in b/ld/Makefile.in
4496
index 9c546d7..557ebb0 100644
4497
--- a/ld/Makefile.in
4498
+++ b/ld/Makefile.in
4499
@@ -634,65 +634,7 @@ ALL_EMULATION_SOURCES = \
4566
@@ -1250,65 +1192,7 @@ distclean-compile:
4567
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emmo.Po@am__quote@
4568
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emn10200.Po@am__quote@
4569
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emn10300.Po@am__quote@
4570
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x110.Po@am__quote@
4571
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x1101.Po@am__quote@
4572
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x1111.Po@am__quote@
4573
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x112.Po@am__quote@
4574
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x1121.Po@am__quote@
4575
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x1122.Po@am__quote@
4576
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x1132.Po@am__quote@
4577
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x122.Po@am__quote@
4578
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x1222.Po@am__quote@
4579
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x123.Po@am__quote@
4580
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x1232.Po@am__quote@
4581
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x133.Po@am__quote@
4582
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x1331.Po@am__quote@
4583
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x135.Po@am__quote@
4584
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x1351.Po@am__quote@
4585
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x147.Po@am__quote@
4586
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x148.Po@am__quote@
4587
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x149.Po@am__quote@
4588
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x155.Po@am__quote@
4589
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x156.Po@am__quote@
4590
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x157.Po@am__quote@
4591
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x1610.Po@am__quote@
4592
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x1611.Po@am__quote@
4593
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x1612.Po@am__quote@
4594
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x167.Po@am__quote@
4595
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x168.Po@am__quote@
4596
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x169.Po@am__quote@
4597
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x2101.Po@am__quote@
4598
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x2111.Po@am__quote@
4599
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x2121.Po@am__quote@
4600
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x2131.Po@am__quote@
4601
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x311.Po@am__quote@
4602
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x312.Po@am__quote@
4603
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x313.Po@am__quote@
4604
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x314.Po@am__quote@
4605
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x315.Po@am__quote@
4606
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x323.Po@am__quote@
4607
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x325.Po@am__quote@
4608
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x336.Po@am__quote@
4609
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x337.Po@am__quote@
4610
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x412.Po@am__quote@
4611
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x413.Po@am__quote@
4612
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x415.Po@am__quote@
4613
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x417.Po@am__quote@
4614
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x435.Po@am__quote@
4615
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x436.Po@am__quote@
4616
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x437.Po@am__quote@
4617
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x447.Po@am__quote@
4618
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x448.Po@am__quote@
4619
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430x449.Po@am__quote@
4620
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430xE423.Po@am__quote@
4621
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430xE425.Po@am__quote@
4622
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430xE427.Po@am__quote@
4623
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430xG437.Po@am__quote@
4624
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430xG438.Po@am__quote@
4625
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430xG439.Po@am__quote@
4626
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430xW423.Po@am__quote@
4627
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430xW425.Po@am__quote@
4628
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430xW427.Po@am__quote@
4629
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430.Po@am__quote@
4630
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enews.Po@am__quote@
4631
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ens32knbsd.Po@am__quote@
4632
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eor32.Po@am__quote@
4633
@@ -2839,242 +2723,10 @@ emn10300.c: $(srcdir)/emulparams/mn10300.sh \
4634
$(srcdir)/emulparams/mn10200.sh \
4635
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
4636
${GENSCRIPTS} mn10300 "$(tdir_mn10300)"
4637
-emsp430x110.c: $(srcdir)/emulparams/msp430all.sh \
4638
+emsp430.c: $(srcdir)/emulparams/msp430uni.sh \
4639
$(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4641
- ${GENSCRIPTS} msp430x110 "$(tdir_msp430x110)" msp430all
4642
-emsp430x1101.c: $(srcdir)/emulparams/msp430all.sh \
4643
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4645
- ${GENSCRIPTS} msp430x1101 "$(tdir_msp430x1101)" msp430all
4646
-emsp430x1111.c: $(srcdir)/emulparams/msp430all.sh \
4647
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4649
- ${GENSCRIPTS} msp430x1111 "$(tdir_msp430x1111)" msp430all
4650
-emsp430x112.c: $(srcdir)/emulparams/msp430all.sh \
4651
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4653
- ${GENSCRIPTS} msp430x112 "$(tdir_msp430x112)" msp430all
4654
-emsp430x1121.c: $(srcdir)/emulparams/msp430all.sh \
4655
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4657
- ${GENSCRIPTS} msp430x1121 "$(tdir_msp430x1121)" msp430all
4658
-emsp430x1122.c: $(srcdir)/emulparams/msp430all.sh \
4659
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4661
- ${GENSCRIPTS} msp430x1122 "$(tdir_msp430x1122)" msp430all
4662
-emsp430x1132.c: $(srcdir)/emulparams/msp430all.sh \
4663
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4665
- ${GENSCRIPTS} msp430x1132 "$(tdir_msp430x1132)" msp430all
4666
-emsp430x122.c: $(srcdir)/emulparams/msp430all.sh \
4667
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4669
- ${GENSCRIPTS} msp430x122 "$(tdir_msp430x122)" msp430all
4670
-emsp430x1222.c: $(srcdir)/emulparams/msp430all.sh \
4671
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4673
- ${GENSCRIPTS} msp430x1222 "$(tdir_msp430x1222)" msp430all
4674
-emsp430x123.c: $(srcdir)/emulparams/msp430all.sh \
4675
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4677
- ${GENSCRIPTS} msp430x123 "$(tdir_msp430x123)" msp430all
4678
-emsp430x1232.c: $(srcdir)/emulparams/msp430all.sh \
4679
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4681
- ${GENSCRIPTS} msp430x1232 "$(tdir_msp430x1232)" msp430all
4682
-emsp430x133.c: $(srcdir)/emulparams/msp430all.sh \
4683
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4685
- ${GENSCRIPTS} msp430x133 "$(tdir_msp430x133)" msp430all
4686
-emsp430x1331.c: $(srcdir)/emulparams/msp430all.sh \
4687
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4689
- ${GENSCRIPTS} msp430x1331 "$(tdir_msp430x1331)" msp430all
4690
-emsp430x135.c: $(srcdir)/emulparams/msp430all.sh \
4691
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4693
- ${GENSCRIPTS} msp430x135 "$(tdir_msp430x135)" msp430all
4694
-emsp430x1351.c: $(srcdir)/emulparams/msp430all.sh \
4695
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4697
- ${GENSCRIPTS} msp430x1351 "$(tdir_msp430x1351)" msp430all
4698
-emsp430x147.c: $(srcdir)/emulparams/msp430all.sh \
4699
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4701
- ${GENSCRIPTS} msp430x147 "$(tdir_msp430x147)" msp430all
4702
-emsp430x148.c: $(srcdir)/emulparams/msp430all.sh \
4703
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4705
- ${GENSCRIPTS} msp430x148 "$(tdir_msp430x148)" msp430all
4706
-emsp430x149.c: $(srcdir)/emulparams/msp430all.sh \
4707
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4709
- ${GENSCRIPTS} msp430x149 "$(tdir_msp430x149)" msp430all
4710
-emsp430x155.c: $(srcdir)/emulparams/msp430all.sh \
4711
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4713
- ${GENSCRIPTS} msp430x155 "$(tdir_msp430x155)" msp430all
4714
-emsp430x156.c: $(srcdir)/emulparams/msp430all.sh \
4715
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4717
- ${GENSCRIPTS} msp430x156 "$(tdir_msp430x156)" msp430all
4718
-emsp430x157.c: $(srcdir)/emulparams/msp430all.sh \
4719
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4721
- ${GENSCRIPTS} msp430x157 "$(tdir_msp430x157)" msp430all
4722
-emsp430x1610.c: $(srcdir)/emulparams/msp430all.sh \
4723
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4725
- ${GENSCRIPTS} msp430x1610 "$(tdir_msp430x1610)" msp430all
4726
-emsp430x1611.c: $(srcdir)/emulparams/msp430all.sh \
4727
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4729
- ${GENSCRIPTS} msp430x1611 "$(tdir_msp430x1611)" msp430all
4730
-emsp430x1612.c: $(srcdir)/emulparams/msp430all.sh \
4731
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4733
- ${GENSCRIPTS} msp430x1612 "$(tdir_msp430x1612)" msp430all
4734
-emsp430x167.c: $(srcdir)/emulparams/msp430all.sh \
4735
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4737
- ${GENSCRIPTS} msp430x167 "$(tdir_msp430x167)" msp430all
4738
-emsp430x168.c: $(srcdir)/emulparams/msp430all.sh \
4739
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4741
- ${GENSCRIPTS} msp430x168 "$(tdir_msp430x168)" msp430all
4742
-emsp430x169.c: $(srcdir)/emulparams/msp430all.sh \
4743
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4745
- ${GENSCRIPTS} msp430x169 "$(tdir_msp430x169)" msp430all
4746
-emsp430x2101.c: $(srcdir)/emulparams/msp430all.sh \
4747
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4749
- ${GENSCRIPTS} msp430x2101 "$(tdir_msp430x2101)" msp430all
4750
-emsp430x2111.c: $(srcdir)/emulparams/msp430all.sh \
4751
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4753
- ${GENSCRIPTS} msp430x2111 "$(tdir_msp430x2111)" msp430all
4754
-emsp430x2121.c: $(srcdir)/emulparams/msp430all.sh \
4755
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4757
- ${GENSCRIPTS} msp430x2121 "$(tdir_msp430x2121)" msp430all
4758
-emsp430x2131.c: $(srcdir)/emulparams/msp430all.sh \
4759
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4761
- ${GENSCRIPTS} msp430x2131 "$(tdir_msp430x2131)" msp430all
4762
-emsp430x311.c: $(srcdir)/emulparams/msp430all.sh \
4763
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \
4765
- ${GENSCRIPTS} msp430x311 "$(tdir_msp430x311)" msp430all
4766
-emsp430x312.c: $(srcdir)/emulparams/msp430all.sh \
4767
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \
4769
- ${GENSCRIPTS} msp430x312 "$(tdir_msp430x312)" msp430all
4770
-emsp430x313.c: $(srcdir)/emulparams/msp430all.sh \
4771
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \
4773
- ${GENSCRIPTS} msp430x313 "$(tdir_msp430x313)" msp430all
4774
-emsp430x314.c: $(srcdir)/emulparams/msp430all.sh \
4775
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \
4777
- ${GENSCRIPTS} msp430x314 "$(tdir_msp430x314)" msp430all
4778
-emsp430x315.c: $(srcdir)/emulparams/msp430all.sh \
4779
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \
4781
- ${GENSCRIPTS} msp430x315 "$(tdir_msp430x315)" msp430all
4782
-emsp430x323.c: $(srcdir)/emulparams/msp430all.sh \
4783
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \
4785
- ${GENSCRIPTS} msp430x323 "$(tdir_msp430x323)" msp430all
4786
-emsp430x325.c: $(srcdir)/emulparams/msp430all.sh \
4787
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \
4789
- ${GENSCRIPTS} msp430x325 "$(tdir_msp430x325)" msp430all
4790
-emsp430x336.c: $(srcdir)/emulparams/msp430all.sh \
4791
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \
4793
- ${GENSCRIPTS} msp430x336 "$(tdir_msp430x336)" msp430all
4794
-emsp430x337.c: $(srcdir)/emulparams/msp430all.sh \
4795
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430_3.sc \
4797
- ${GENSCRIPTS} msp430x337 "$(tdir_msp430x337)" msp430all
4798
-emsp430x412.c: $(srcdir)/emulparams/msp430all.sh \
4799
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4801
- ${GENSCRIPTS} msp430x412 "$(tdir_msp430x412)" msp430all
4802
-emsp430x413.c: $(srcdir)/emulparams/msp430all.sh \
4803
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4805
- ${GENSCRIPTS} msp430x413 "$(tdir_msp430x413)" msp430all
4806
-emsp430x415.c: $(srcdir)/emulparams/msp430all.sh \
4807
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4809
- ${GENSCRIPTS} msp430x415 "$(tdir_msp430x415)" msp430all
4810
-emsp430x417.c: $(srcdir)/emulparams/msp430all.sh \
4811
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4813
- ${GENSCRIPTS} msp430x417 "$(tdir_msp430x417)" msp430all
4814
-emsp430x435.c: $(srcdir)/emulparams/msp430all.sh \
4815
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4817
- ${GENSCRIPTS} msp430x435 "$(tdir_msp430x435)" msp430all
4818
-emsp430x436.c: $(srcdir)/emulparams/msp430all.sh \
4819
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4821
- ${GENSCRIPTS} msp430x436 "$(tdir_msp430x436)" msp430all
4822
-emsp430x437.c: $(srcdir)/emulparams/msp430all.sh \
4823
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4825
- ${GENSCRIPTS} msp430x437 "$(tdir_msp430x437)" msp430all
4826
-emsp430x447.c: $(srcdir)/emulparams/msp430all.sh \
4827
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4829
- ${GENSCRIPTS} msp430x447 "$(tdir_msp430x447)" msp430all
4830
-emsp430x448.c: $(srcdir)/emulparams/msp430all.sh \
4831
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4833
- ${GENSCRIPTS} msp430x448 "$(tdir_msp430x448)" msp430all
4834
-emsp430x449.c: $(srcdir)/emulparams/msp430all.sh \
4835
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4837
- ${GENSCRIPTS} msp430x449 "$(tdir_msp430x449)" msp430all
4838
-emsp430xE423.c: $(srcdir)/emulparams/msp430all.sh \
4839
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4841
- ${GENSCRIPTS} msp430xE423 "$(tdir_msp430xE423)" msp430all
4842
-emsp430xE425.c: $(srcdir)/emulparams/msp430all.sh \
4843
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4845
- ${GENSCRIPTS} msp430xE425 "$(tdir_msp430xE425)" msp430all
4846
-emsp430xE427.c: $(srcdir)/emulparams/msp430all.sh \
4847
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4849
- ${GENSCRIPTS} msp430xE427 "$(tdir_msp430xE427)" msp430all
4850
-emsp430xG437.c: $(srcdir)/emulparams/msp430all.sh \
4851
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4853
- ${GENSCRIPTS} msp430xG437 "$(tdir_msp430xG437)" msp430all
4854
-emsp430xG438.c: $(srcdir)/emulparams/msp430all.sh \
4855
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4857
- ${GENSCRIPTS} msp430xG438 "$(tdir_msp430xG438)" msp430all
4858
-emsp430xG439.c: $(srcdir)/emulparams/msp430all.sh \
4859
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4861
- ${GENSCRIPTS} msp430xG439 "$(tdir_msp430xG439)" msp430all
4862
-emsp430xW423.c: $(srcdir)/emulparams/msp430all.sh \
4863
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4865
- ${GENSCRIPTS} msp430xW423 "$(tdir_msp430xW423)" msp430all
4866
-emsp430xW425.c: $(srcdir)/emulparams/msp430all.sh \
4867
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4869
- ${GENSCRIPTS} msp430xW425 "$(tdir_msp430xW425)" msp430all
4870
-emsp430xW427.c: $(srcdir)/emulparams/msp430all.sh \
4871
- $(ELF_GEN_DEPS) $(srcdir)/scripttempl/elf32msp430.sc \
4873
- ${GENSCRIPTS} msp430xW427 "$(tdir_msp430xW427)" msp430all
4874
+ ${GENSCRIPTS} msp430 "$(tdir_msp430)" msp430uni
4875
enews.c: $(srcdir)/emulparams/news.sh \
4876
$(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
4877
${GENSCRIPTS} news "$(tdir_news)"
4878
diff --git a/ld/configure.tgt b/ld/configure.tgt
4879
index 7528cb5..98c4022 100644
4880
--- a/ld/configure.tgt
4881
+++ b/ld/configure.tgt
4882
@@ -433,8 +433,7 @@ mn10300-*-*) targ_emul=mn10300
4884
mt-*elf) targ_emul=elf32mt
4886
-msp430-*-*) targ_emul=msp430x110
4887
- targ_extra_emuls="msp430x112 msp430x1101 msp430x1111 msp430x1121 msp430x1122 msp430x1132 msp430x122 msp430x123 msp430x1222 msp430x1232 msp430x133 msp430x135 msp430x1331 msp430x1351 msp430x147 msp430x148 msp430x149 msp430x155 msp430x156 msp430x157 msp430x167 msp430x168 msp430x169 msp430x1610 msp430x1611 msp430x1612 msp430x2101 msp430x2111 msp430x2121 msp430x2131 msp430x311 msp430x312 msp430x313 msp430x314 msp430x315 msp430x323 msp430x325 msp430x336 msp430x337 msp430x412 msp430x413 msp430x415 msp430x417 msp430xE423 msp430xE425 msp430xE427 msp430xW423 msp430xW425 msp430xW427 msp430xG437 msp430xG438 msp430xG439 msp430x435 msp430x436 msp430x437 msp430x447 msp430x448 msp430x449"
4888
+msp430-*-*) targ_emul=msp430
4890
ns32k-pc532-mach* | ns32k-pc532-ux*) targ_emul=pc532macha ;;
4891
ns32k-*-netbsd* | ns32k-pc532-lites*) targ_emul=ns32knbsd
4892
diff --git a/ld/emulparams/msp430all.sh b/ld/emulparams/msp430all.sh
4893
deleted file mode 100644
4894
index 57d21c2..0000000
4895
--- a/ld/emulparams/msp430all.sh
4900
-# This called by genscripts_extra.sh
4902
-MSP430_NAME=${EMULATION_NAME}
4904
-SCRIPT_NAME=elf32msp430
4905
-TEMPLATE_NAME=generic
4906
-EXTRA_EM_FILE=genelf
4907
-OUTPUT_FORMAT="elf32-msp430"
4912
-if [ "${MSP430_NAME}" = "msp430x110" ] ; then
4921
-if [ "${MSP430_NAME}" = "msp430x1101" ] ; then
4930
-if [ "${MSP430_NAME}" = "msp430x1111" ] ; then
4939
-if [ "${MSP430_NAME}" = "msp430x112" ] ; then
4948
-if [ "${MSP430_NAME}" = "msp430x1121" ] ; then
4957
-if [ "${MSP430_NAME}" = "msp430x1122" ] ; then
4966
-if [ "${MSP430_NAME}" = "msp430x1132" ] ; then
4975
-if [ "${MSP430_NAME}" = "msp430x122" ] ; then
4984
-if [ "${MSP430_NAME}" = "msp430x1222" ] ; then
4993
-if [ "${MSP430_NAME}" = "msp430x123" ] ; then
5002
-if [ "${MSP430_NAME}" = "msp430x1232" ] ; then
5011
-if [ "${MSP430_NAME}" = "msp430x133" ] ; then
5020
-if [ "${MSP430_NAME}" = "msp430x1331" ] ; then
5029
-if [ "${MSP430_NAME}" = "msp430x135" ] ; then
5038
-if [ "${MSP430_NAME}" = "msp430x1351" ] ; then
5047
-if [ "${MSP430_NAME}" = "msp430x147" ] ; then
5056
-if [ "${MSP430_NAME}" = "msp430x148" ] ; then
5065
-if [ "${MSP430_NAME}" = "msp430x149" ] ; then
5074
-if [ "${MSP430_NAME}" = "msp430x155" ] ; then
5083
-if [ "${MSP430_NAME}" = "msp430x156" ] ; then
5092
-if [ "${MSP430_NAME}" = "msp430x157" ] ; then
5101
-if [ "${MSP430_NAME}" = "msp430x167" ] ; then
5110
-if [ "${MSP430_NAME}" = "msp430x168" ] ; then
5119
-if [ "${MSP430_NAME}" = "msp430x169" ] ; then
5128
-if [ "${MSP430_NAME}" = "msp430x1610" ] ; then
5137
-if [ "${MSP430_NAME}" = "msp430x1611" ] ; then
5146
-if [ "${MSP430_NAME}" = "msp430x1612" ] ; then
5155
-if [ "${MSP430_NAME}" = "msp430x2101" ] ; then
5164
-if [ "${MSP430_NAME}" = "msp430x2111" ] ; then
5173
-if [ "${MSP430_NAME}" = "msp430x2121" ] ; then
5182
-if [ "${MSP430_NAME}" = "msp430x2131" ] ; then
5191
-if [ "${MSP430_NAME}" = "msp430x311" ] ; then
5193
-SCRIPT_NAME=elf32msp430_3
5201
-if [ "${MSP430_NAME}" = "msp430x312" ] ; then
5203
-SCRIPT_NAME=elf32msp430_3
5211
-if [ "${MSP430_NAME}" = "msp430x313" ] ; then
5213
-SCRIPT_NAME=elf32msp430_3
5221
-if [ "${MSP430_NAME}" = "msp430x314" ] ; then
5223
-SCRIPT_NAME=elf32msp430_3
5231
-if [ "${MSP430_NAME}" = "msp430x315" ] ; then
5233
-SCRIPT_NAME=elf32msp430_3
5241
-if [ "${MSP430_NAME}" = "msp430x323" ] ; then
5243
-SCRIPT_NAME=elf32msp430_3
5251
-if [ "${MSP430_NAME}" = "msp430x325" ] ; then
5253
-SCRIPT_NAME=elf32msp430_3
5261
-if [ "${MSP430_NAME}" = "msp430x336" ] ; then
5263
-SCRIPT_NAME=elf32msp430_3
5271
-if [ "${MSP430_NAME}" = "msp430x337" ] ; then
5273
-SCRIPT_NAME=elf32msp430_3
5281
-if [ "${MSP430_NAME}" = "msp430x412" ] ; then
5290
-if [ "${MSP430_NAME}" = "msp430x413" ] ; then
5299
-if [ "${MSP430_NAME}" = "msp430x415" ] ; then
5308
-if [ "${MSP430_NAME}" = "msp430x417" ] ; then
5317
-if [ "${MSP430_NAME}" = "msp430x435" ] ; then
5326
-if [ "${MSP430_NAME}" = "msp430x436" ] ; then
5335
-if [ "${MSP430_NAME}" = "msp430x437" ] ; then
5344
-if [ "${MSP430_NAME}" = "msp430x447" ] ; then
5353
-if [ "${MSP430_NAME}" = "msp430x448" ] ; then
5362
-if [ "${MSP430_NAME}" = "msp430x449" ] ; then
5371
-if [ "${MSP430_NAME}" = "msp430xE423" ] ; then
5380
-if [ "${MSP430_NAME}" = "msp430xE425" ] ; then
5389
-if [ "${MSP430_NAME}" = "msp430xE427" ] ; then
5398
-if [ "${MSP430_NAME}" = "msp430xG437" ] ; then
5407
-if [ "${MSP430_NAME}" = "msp430xG438" ] ; then
5416
-if [ "${MSP430_NAME}" = "msp430xG439" ] ; then
5425
-if [ "${MSP430_NAME}" = "msp430xW423" ] ; then
5434
-if [ "${MSP430_NAME}" = "msp430xW425" ] ; then
5443
-if [ "${MSP430_NAME}" = "msp430xW427" ] ; then
5451
diff --git a/ld/emulparams/msp430uni.sh b/ld/emulparams/msp430uni.sh
5452
new file mode 100644
5453
index 0000000..ac7473f
5455
+++ b/ld/emulparams/msp430uni.sh
5459
+# This called by genscripts_extra.sh
5461
+MSP430_NAME=${EMULATION_NAME}
5462
+SCRIPT_NAME=elf32msp430
5463
+TEMPLATE_NAME=generic
5464
+EXTRA_EM_FILE=msp430
5465
+OUTPUT_FORMAT="elf32-msp430"
5470
diff --git a/ld/emultempl/msp430.em b/ld/emultempl/msp430.em
5471
new file mode 100644
5472
index 0000000..f4586f8
5474
+++ b/ld/emultempl/msp430.em
5476
+# This shell script emits a C file. -*- C -*-
5477
+# Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
5479
+# This file is part of the GNU Binutils.
5481
+# This program is free software; you can redistribute it and/or modify
5482
+# it under the terms of the GNU General Public License as published by
5483
+# the Free Software Foundation; either version 3 of the License, or
5484
+# (at your option) any later version.
5486
+# This program is distributed in the hope that it will be useful,
5487
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
5488
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5489
+# GNU General Public License for more details.
5491
+# You should have received a copy of the GNU General Public License
5492
+# along with this program; if not, write to the Free Software
5493
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
5494
+# MA 02110-1301, USA.
5497
+# Adapt genelf.em for MSP430
5498
+# This file is sourced from generic.em
5501
+#include "elf-bfd.h"
5502
+#include "libbfd.h"
5503
+#include "elf/msp430.h"
5506
+source_em ${srcdir}/emultempl/elf-generic.em
5510
+gld${EMULATION_NAME}_after_open (void)
5516
+ after_open_default ();
5518
+ if (link_info.relocatable)
5519
+ for (ibfd = link_info.input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
5520
+ if ((syms = bfd_get_outsymbols (ibfd)) != NULL
5521
+ && bfd_get_flavour (ibfd) == bfd_target_elf_flavour)
5522
+ for (sec = ibfd->sections; sec != NULL; sec = sec->next)
5523
+ if ((sec->flags & (SEC_GROUP | SEC_LINKER_CREATED)) == SEC_GROUP)
5525
+ struct bfd_elf_section_data *sec_data = elf_section_data (sec);
5526
+ elf_group_id (sec) = syms[sec_data->this_hdr.sh_info - 1];
5531
+gld${EMULATION_NAME}_before_allocation (void)
5533
+ if (link_info.relocatable
5534
+ && !_bfd_elf_size_group_sections (&link_info))
5535
+ einfo ("%X%P: can not size group sections: %E\n");
5536
+ before_allocation_default ();
5540
+gld${EMULATION_NAME}_after_allocation (void)
5542
+ gld${EMULATION_NAME}_map_segments (FALSE);
5546
+gld${EMULATION_NAME}_finish (void)
5548
+ bfd *obfd = link_info.output_bfd;
5549
+ Elf_Internal_Ehdr *o_ehdrp = elf_elfheader (obfd);
5550
+ unsigned long flags = 0;
5553
+ for (ibfd = link_info.input_bfds; ibfd != NULL; ibfd = ibfd->link_next) {
5554
+ Elf_Internal_Ehdr * i_ehdrp = elf_elfheader (ibfd);
5556
+ if (EF_MSP430_UNIARCH & i_ehdrp->e_flags)
5557
+ flags |= i_ehdrp->e_flags;
5559
+ if (EF_MSP430_UNIARCH & flags) {
5561
+ switch (flags & EF_MSP430_ARCH)
5564
+ case EF_MSP430_ARCH_430:
5565
+ bfd_mach = bfd_mach_msp430;
5567
+ case EF_MSP430_ARCH_430X:
5568
+ bfd_mach = bfd_mach_msp430x;
5571
+ bfd_default_set_arch_mach (obfd, bfd_arch_msp430, bfd_mach);
5572
+ o_ehdrp->e_flags = flags;
5577
+# Put these extra routines in ld_${EMULATION_NAME}_emulation
5579
+LDEMUL_AFTER_OPEN=gld${EMULATION_NAME}_after_open
5580
+LDEMUL_BEFORE_ALLOCATION=gld${EMULATION_NAME}_before_allocation
5581
+LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation
5582
+LDEMUL_FINISH=gld${EMULATION_NAME}_finish
5583
diff --git a/ld/scripttempl/elf32msp430.sc b/ld/scripttempl/elf32msp430.sc
5584
index cbffe48..cb3e754 100644
5585
--- a/ld/scripttempl/elf32msp430.sc
5586
+++ b/ld/scripttempl/elf32msp430.sc
5590
-HEAP_SECTION_MSP430=" "
5591
-HEAP_MEMORY_MSP430=" "
5593
-if test ${GOT_HEAP_MSP-0} -ne 0
5595
-HEAP_SECTION_MSP430=".heap ${RELOCATING-0} :
5597
- ${RELOCATING+ PROVIDE (__heap_data_start = .) ; }
5599
- ${RELOCATING+ PROVIDE (_heap_data_end = .) ; }
5600
- ${RELOCATING+. = ALIGN(2);}
5601
- ${RELOCATING+ PROVIDE (__heap_bottom = .) ; }
5602
- ${RELOCATING+ PROVIDE (__heap_top = ${HEAP_START} + ${HEAP_LENGTH}) ; }
5603
- } ${RELOCATING+ > heap}"
5604
-HEAP_MEMORY_MSP430="heap(rwx) : ORIGIN = $HEAP_START, LENGTH = $HEAP_LENGTH"
5609
-OUTPUT_FORMAT("${OUTPUT_FORMAT}","${OUTPUT_FORMAT}","${OUTPUT_FORMAT}")
5610
-OUTPUT_ARCH(${ARCH})
5611
+OUTPUT_FORMAT("${OUTPUT_FORMAT}")
5612
+OUTPUT_ARCH("${MSP430_NAME}")
5616
- text (rx) : ORIGIN = $ROM_START, LENGTH = $ROM_SIZE
5617
- data (rwx) : ORIGIN = $RAM_START, LENGTH = $RAM_SIZE
5618
- vectors (rw) : ORIGIN = 0xffe0, LENGTH = 0x20
5619
- bootloader(rx) : ORIGIN = 0x0c00, LENGTH = 1K
5620
- infomem(rx) : ORIGIN = 0x1000, LENGTH = 256
5621
- infomemnobits(rx) : ORIGIN = 0x1000, LENGTH = 256
5622
- ${HEAP_MEMORY_MSP430}
5624
+${RELOCATING+INCLUDE "memory.x"}
5625
+${RELOCATING+INCLUDE "periph.x"}
5629
@@ -98,109 +72,104 @@ SECTIONS
5630
/* Internal text space. */
5633
- ${RELOCATING+. = ALIGN(2);}
5635
- *(.init0) /* Start here after reset. */
5637
- *(.init2) /* Copy data loop */
5639
- *(.init4) /* Clear bss */
5641
- *(.init6) /* C++ constructors. */
5644
- *(.init9) /* Call main(). */
5645
+ ${RELOCATING+ . = ALIGN(2);}
5647
+ *(.init0) /* Start here after reset. */
5648
+ *(.init1) /* User definable. */
5649
+ *(.init2) /* Initialize stack. */
5650
+ *(.init3) /* Initialize hardware, user definable. */
5651
+ *(.init4) /* Copy data to .data, clear bss. */
5652
+ *(.init5) /* User definable. */
5653
+ *(.init6) /* C++ constructors. */
5654
+ *(.init7) /* User definable. */
5655
+ *(.init8) /* User definable. */
5656
+ *(.init9) /* Call main(). */
5657
+ *(.fini9) /* Falls into here after main(). User definable. */
5658
+ *(.fini8) /* User definable. */
5659
+ *(.fini7) /* User definable. */
5660
+ *(.fini6) /* C++ destructors. */
5661
+ *(.fini5) /* User definable. */
5662
+ *(.fini4) /* User definable. */
5663
+ *(.fini3) /* User definable. */
5664
+ *(.fini2) /* User definable. */
5665
+ *(.fini1) /* User definable. */
5666
+ *(.fini0) /* Infinite loop after program termination. */
5669
+ ${CONSTRUCTING+ . = ALIGN(2); }
5670
${CONSTRUCTING+ __ctors_start = . ; }
5671
- ${CONSTRUCTING+ *(.ctors) }
5672
+ ${CONSTRUCTING+ KEEP(*(.ctors)) }
5673
${CONSTRUCTING+ __ctors_end = . ; }
5674
${CONSTRUCTING+ __dtors_start = . ; }
5675
- ${CONSTRUCTING+ *(.dtors) }
5676
+ ${CONSTRUCTING+ KEEP(*(.dtors)) }
5677
${CONSTRUCTING+ __dtors_end = . ; }
5679
- ${RELOCATING+. = ALIGN(2);}
5680
+ ${RELOCATING+ . = ALIGN(2);}
5682
- ${RELOCATING+. = ALIGN(2);}
5683
+ ${RELOCATING+ . = ALIGN(2);}
5686
- ${RELOCATING+. = ALIGN(2);}
5690
- *(.fini6) /* C++ destructors. */
5696
- *(.fini0) /* Infinite loop after program termination. */
5698
+ ${RELOCATING+ _etext = .;}
5699
+ } ${RELOCATING+ > REGION_TEXT}
5702
- } ${RELOCATING+ > text}
5704
- .data ${RELOCATING-0} : ${RELOCATING+AT (ADDR (.text) + SIZEOF (.text))}
5705
+ .data ${RELOCATING-0} :
5707
+ ${RELOCATING+ . = ALIGN(2);}
5708
${RELOCATING+ PROVIDE (__data_start = .) ; }
5709
- ${RELOCATING+. = ALIGN(2);}
5711
- ${RELOCATING+. = ALIGN(2);}
5712
+ *(SORT_BY_ALIGNMENT(.data.*))
5713
+ ${RELOCATING+ . = ALIGN(2);}
5715
- ${RELOCATING+. = ALIGN(2);}
5716
+ ${RELOCATING+ . = ALIGN(2);}
5717
${RELOCATING+ _edata = . ; }
5718
- } ${RELOCATING+ > data}
5719
+ } ${RELOCATING+ > REGION_DATA AT > REGION_TEXT}
5720
+ ${RELOCATING+ PROVIDE (__data_load_start = LOADADDR(.data) ); }
5721
+ ${RELOCATING+ PROVIDE (__data_size = SIZEOF(.data) ); }
5724
- .bootloader ${RELOCATING-0} :
5726
- ${RELOCATING+ PROVIDE (__boot_start = .) ; }
5728
- ${RELOCATING+. = ALIGN(2);}
5730
- } ${RELOCATING+ > bootloader}
5732
- /* Information memory. */
5733
- .infomem ${RELOCATING-0} :
5736
- ${RELOCATING+. = ALIGN(2);}
5738
- } ${RELOCATING+ > infomem}
5740
- /* Information memory (not loaded into MPU). */
5741
- .infomemnobits ${RELOCATING-0} :
5744
- ${RELOCATING+. = ALIGN(2);}
5745
- *(.infomemnobits.*)
5746
- } ${RELOCATING+ > infomemnobits}
5748
- .bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} :
5749
+ .bss ${RELOCATING-0} :
5751
${RELOCATING+ PROVIDE (__bss_start = .) ; }
5753
+ *(SORT_BY_ALIGNMENT(.bss.*))
5755
${RELOCATING+ PROVIDE (__bss_end = .) ; }
5756
${RELOCATING+ _end = . ; }
5757
- } ${RELOCATING+ > data}
5758
+ } ${RELOCATING+ > REGION_DATA}
5759
+ ${RELOCATING+ PROVIDE (__bss_size = SIZEOF(.bss) ); }
5761
- .noinit ${RELOCATING+ SIZEOF(.bss) + ADDR(.bss)} :
5762
+ .noinit ${RELOCATING-0} :
5764
${RELOCATING+ PROVIDE (__noinit_start = .) ; }
5768
${RELOCATING+ PROVIDE (__noinit_end = .) ; }
5769
${RELOCATING+ _end = . ; }
5770
- } ${RELOCATING+ > data}
5771
+ } ${RELOCATING+ > REGION_DATA}
5773
+ /* Information memory. */
5774
+ .infomem ${RELOCATING-0} :
5777
+ ${RELOCATING+ . = ALIGN(2);}
5779
+ } ${RELOCATING+ > infomem}
5781
.vectors ${RELOCATING-0}:
5783
${RELOCATING+ PROVIDE (__vectors_start = .) ; }
5785
+ KEEP(*(.vectors*))
5786
${RELOCATING+ _vectors_end = . ; }
5787
} ${RELOCATING+ > vectors}
5789
- ${HEAP_SECTION_MSP430}
5792
+ ${RELOCATING+ . = ALIGN(2);}
5794
+ ${RELOCATING+ . = ALIGN(2);}
5796
+ ${RELOCATING+ _efartext = .;}
5797
+ } ${RELOCATING+ > REGION_FAR_ROM}
5799
/* Stabs for profiling information*/
5800
.profiler 0 : { *(.profiler) }
5801
@@ -239,11 +208,14 @@ SECTIONS
5802
.debug_loc 0 : { *(.debug_loc) }
5803
.debug_macinfo 0 : { *(.debug_macinfo) }
5805
- PROVIDE (__stack = ${STACK}) ;
5806
- PROVIDE (__data_start_rom = _etext) ;
5807
- PROVIDE (__data_end_rom = _etext + SIZEOF (.data)) ;
5808
- PROVIDE (__noinit_start_rom = _etext + SIZEOF (.data)) ;
5809
- PROVIDE (__noinit_end_rom = _etext + SIZEOF (.data) + SIZEOF (.noinit)) ;
5810
- PROVIDE (__subdevice_has_heap = ${GOT_HEAP_MSP-0}) ;
5812
+ .debug_pubtypes 0 : { *(.debug_pubtypes) }
5813
+ .debug_ranges 0 : { *(.debug_ranges) }
5815
+ ${RELOCATING+ PROVIDE (__stack = ORIGIN(ram) + LENGTH(ram));}
5816
+ ${RELOCATING+ PROVIDE (__data_start_rom = _etext);}
5817
+ ${RELOCATING+ PROVIDE (__data_end_rom = _etext + SIZEOF (.data));}
5818
+ ${RELOCATING+ PROVIDE (__noinit_start_rom = _etext + SIZEOF (.data));}
5819
+ ${RELOCATING+ PROVIDE (__noinit_end_rom = _etext + SIZEOF (.data) + SIZEOF (.noinit));}
5822
diff --git a/ld/scripttempl/elf32msp430_3.sc b/ld/scripttempl/elf32msp430_3.sc
5823
deleted file mode 100644
5824
index 15eb517..0000000
5825
--- a/ld/scripttempl/elf32msp430_3.sc
5829
-OUTPUT_FORMAT("${OUTPUT_FORMAT}","${OUTPUT_FORMAT}","${OUTPUT_FORMAT}")
5830
-OUTPUT_ARCH(${ARCH})
5834
- text (rx) : ORIGIN = $ROM_START, LENGTH = $ROM_SIZE
5835
- data (rwx) : ORIGIN = $RAM_START, LENGTH = $RAM_SIZE
5836
- vectors (rw) : ORIGIN = 0xffe0, LENGTH = 0x20
5841
- /* Read-only sections, merged into text segment. */
5842
- ${TEXT_DYNAMIC+${DYNAMIC}}
5843
- .hash ${RELOCATING-0} : { *(.hash) }
5844
- .dynsym ${RELOCATING-0} : { *(.dynsym) }
5845
- .dynstr ${RELOCATING-0} : { *(.dynstr) }
5846
- .gnu.version ${RELOCATING-0} : { *(.gnu.version) }
5847
- .gnu.version_d ${RELOCATING-0} : { *(.gnu.version_d) }
5848
- .gnu.version_r ${RELOCATING-0} : { *(.gnu.version_r) }
5850
- .rel.init ${RELOCATING-0} : { *(.rel.init) }
5851
- .rela.init ${RELOCATING-0} : { *(.rela.init) }
5852
- .rel.text ${RELOCATING-0} :
5855
- ${RELOCATING+*(.rel.text.*)}
5856
- ${RELOCATING+*(.rel.gnu.linkonce.t*)}
5858
- .rela.text ${RELOCATING-0} :
5861
- ${RELOCATING+*(.rela.text.*)}
5862
- ${RELOCATING+*(.rela.gnu.linkonce.t*)}
5864
- .rel.fini ${RELOCATING-0} : { *(.rel.fini) }
5865
- .rela.fini ${RELOCATING-0} : { *(.rela.fini) }
5866
- .rel.rodata ${RELOCATING-0} :
5869
- ${RELOCATING+*(.rel.rodata.*)}
5870
- ${RELOCATING+*(.rel.gnu.linkonce.r*)}
5872
- .rela.rodata ${RELOCATING-0} :
5875
- ${RELOCATING+*(.rela.rodata.*)}
5876
- ${RELOCATING+*(.rela.gnu.linkonce.r*)}
5878
- .rel.data ${RELOCATING-0} :
5881
- ${RELOCATING+*(.rel.data.*)}
5882
- ${RELOCATING+*(.rel.gnu.linkonce.d*)}
5884
- .rela.data ${RELOCATING-0} :
5887
- ${RELOCATING+*(.rela.data.*)}
5888
- ${RELOCATING+*(.rela.gnu.linkonce.d*)}
5890
- .rel.ctors ${RELOCATING-0} : { *(.rel.ctors) }
5891
- .rela.ctors ${RELOCATING-0} : { *(.rela.ctors) }
5892
- .rel.dtors ${RELOCATING-0} : { *(.rel.dtors) }
5893
- .rela.dtors ${RELOCATING-0} : { *(.rela.dtors) }
5894
- .rel.got ${RELOCATING-0} : { *(.rel.got) }
5895
- .rela.got ${RELOCATING-0} : { *(.rela.got) }
5896
- .rel.bss ${RELOCATING-0} : { *(.rel.bss) }
5897
- .rela.bss ${RELOCATING-0} : { *(.rela.bss) }
5898
- .rel.plt ${RELOCATING-0} : { *(.rel.plt) }
5899
- .rela.plt ${RELOCATING-0} : { *(.rela.plt) }
5901
- /* Internal text space. */
5904
- ${RELOCATING+. = ALIGN(2);}
5906
- *(.init0) /* Start here after reset. */
5912
- *(.init6) /* C++ constructors. */
5915
- *(.init9) /* Call main(). */
5917
- ${CONSTRUCTING+ __ctors_start = . ; }
5918
- ${CONSTRUCTING+ *(.ctors) }
5919
- ${CONSTRUCTING+ __ctors_end = . ; }
5920
- ${CONSTRUCTING+ __dtors_start = . ; }
5921
- ${CONSTRUCTING+ *(.dtors) }
5922
- ${CONSTRUCTING+ __dtors_end = . ; }
5924
- ${RELOCATING+. = ALIGN(2);}
5926
- ${RELOCATING+. = ALIGN(2);}
5929
- ${RELOCATING+. = ALIGN(2);}
5933
- *(.fini6) /* C++ destructors. */
5939
- *(.fini0) /* Infinite loop after program termination. */
5942
- ${RELOCATING+ _etext = . ; }
5943
- } ${RELOCATING+ > text}
5945
- .data ${RELOCATING-0} : ${RELOCATING+AT (ADDR (.text) + SIZEOF (.text))}
5947
- ${RELOCATING+ PROVIDE (__data_start = .) ; }
5949
- *(.gnu.linkonce.d*)
5950
- ${RELOCATING+. = ALIGN(2);}
5951
- ${RELOCATING+ _edata = . ; }
5952
- } ${RELOCATING+ > data}
5954
- .bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} :
5956
- ${RELOCATING+ PROVIDE (__bss_start = .) ; }
5959
- ${RELOCATING+ PROVIDE (__bss_end = .) ; }
5960
- ${RELOCATING+ _end = . ; }
5961
- } ${RELOCATING+ > data}
5963
- .noinit ${RELOCATING+ SIZEOF(.bss) + ADDR(.bss)} :
5965
- ${RELOCATING+ PROVIDE (__noinit_start = .) ; }
5968
- ${RELOCATING+ PROVIDE (__noinit_end = .) ; }
5969
- ${RELOCATING+ _end = . ; }
5970
- } ${RELOCATING+ > data}
5972
- .vectors ${RELOCATING-0}:
5974
- ${RELOCATING+ PROVIDE (__vectors_start = .) ; }
5976
- ${RELOCATING+ _vectors_end = . ; }
5977
- } ${RELOCATING+ > vectors}
5979
- /* Stabs debugging sections. */
5980
- .stab 0 : { *(.stab) }
5981
- .stabstr 0 : { *(.stabstr) }
5982
- .stab.excl 0 : { *(.stab.excl) }
5983
- .stab.exclstr 0 : { *(.stab.exclstr) }
5984
- .stab.index 0 : { *(.stab.index) }
5985
- .stab.indexstr 0 : { *(.stab.indexstr) }
5986
- .comment 0 : { *(.comment) }
5988
- /* DWARF debug sections.
5989
- Symbols in the DWARF debugging sections are relative to the beginning
5990
- of the section so we begin them at 0. */
5993
- .debug 0 : { *(.debug) }
5994
- .line 0 : { *(.line) }
5996
- /* GNU DWARF 1 extensions */
5997
- .debug_srcinfo 0 : { *(.debug_srcinfo) }
5998
- .debug_sfnames 0 : { *(.debug_sfnames) }
6000
- /* DWARF 1.1 and DWARF 2 */
6001
- .debug_aranges 0 : { *(.debug_aranges) }
6002
- .debug_pubnames 0 : { *(.debug_pubnames) }
6005
- .debug_info 0 : { *(.debug_info) *(.gnu.linkonce.wi.*) }
6006
- .debug_abbrev 0 : { *(.debug_abbrev) }
6007
- .debug_line 0 : { *(.debug_line) }
6008
- .debug_frame 0 : { *(.debug_frame) }
6009
- .debug_str 0 : { *(.debug_str) }
6010
- .debug_loc 0 : { *(.debug_loc) }
6011
- .debug_macinfo 0 : { *(.debug_macinfo) }
6013
- PROVIDE (__stack = ${STACK}) ;
6014
- PROVIDE (__data_start_rom = _etext) ;
6015
- PROVIDE (__data_end_rom = _etext + SIZEOF (.data)) ;
6016
- PROVIDE (__noinit_start_rom = _etext + SIZEOF (.data)) ;
6017
- PROVIDE (__noinit_end_rom = _etext + SIZEOF (.data) + SIZEOF (.noinit)) ;
6020
diff --git a/opcodes/msp430-dis.c b/opcodes/msp430-dis.c
6021
index 9d7edbe..a00c718 100644
6022
--- a/opcodes/msp430-dis.c
6023
+++ b/opcodes/msp430-dis.c
6024
@@ -52,12 +52,153 @@ msp430dis_opcode (bfd_vma addr, disassemble_info *info)
6025
return bfd_getl16 (buffer);
6028
+static unsigned short
6029
+msp430dis_operand (bfd_vma addr, disassemble_info *info, int reg, int am, int *cmd_len)
6031
+ static int const op_length [][5] =
6033
+ // am | reg 0 1 2 3 >3
6034
+ /* 0 */ { 0, 0, 0, 0, 0 }, // Rn
6035
+ /* 1 */ { 2, 2, 2, 0, 2 }, // x(Rn)
6036
+ /* 2 */ { 0, 0, 0, 0, 0 }, // @Rn
6037
+ /* 3 */ { 2, 0, 0, 0, 0 }, // @Rn+
6039
+ if (reg >= (int)(sizeof(op_length[0]) / sizeof(op_length[0][0])))
6040
+ reg = sizeof(op_length[0]) / sizeof(op_length[0][0])- 1;
6042
+ if (op_length[am][reg])
6044
+ bfd_byte buffer[2];
6045
+ int status = info->read_memory_func (addr, buffer, 2, info);
6048
+ info->memory_error_func (status, addr, info);
6052
+ return bfd_getl16 (buffer);
6067
+msp430x_decode_operand(int reg, int am, int addr, int dst, operand_t size, char *op, char *comm)
6069
+ if (op) // if operand not hidden in emulated instruction
6075
+ sprintf (op, "#0"); // constant #0
6076
+ sprintf (comm, "r3 As==00");
6080
+ sprintf (op, "r%d", reg);
6084
+ if (reg == 0) // Symbolic, ADDR
6086
+ if (size == OP_20BIT || size == OP_20BIT_HEX)
6087
+ sprintf (op, "0x%05x", dst & 0xfffff);
6089
+ sprintf (op, "0x%04x", dst & 0xffff);
6090
+ sprintf (comm, "PC rel. 0x%05x", ((int)addr + dst) & 0xfffff);
6092
+ else if (reg == 2) // Absolute, &ADDR
6094
+ if (size == OP_20BIT || size == OP_20BIT_HEX)
6095
+ sprintf (op, "&0x%05x", dst & 0xfffff);
6097
+ sprintf (op, "&0x%04x", dst & 0xffff);
6099
+ else if (reg == 3) // constant #1
6101
+ sprintf (op, "#1");
6102
+ sprintf (comm, "r3 As==01");
6104
+ else // Indexed, x(Rn)
6106
+ sprintf (op, "%d(r%d)", dst, reg);
6107
+ if (size == OP_20BIT || size == OP_20BIT_HEX)
6108
+ sprintf (comm, "0x%05x(r%d)", dst & 0xfffff, reg);
6110
+ sprintf (comm, "0x%04x(r%d)", dst & 0xffff, reg);
6114
+ if (reg == 2) // constant #4
6116
+ sprintf (op, "#4");
6117
+ sprintf (comm, "r2 As==10");
6119
+ else if(reg == 3) // constant #2
6121
+ sprintf (op, "#2");
6122
+ sprintf (comm, "r3 As==10");
6126
+ sprintf (op, "@r%d", reg);
6132
+ case 0: // immediate, #N
6136
+ sprintf (op, "#%d", dst);
6137
+ sprintf (comm, "#0x%04x", dst & 0xffff);
6139
+ case OP_16BIT_HEX:
6140
+ sprintf (op, "#0x%04x", dst & 0xffff);
6143
+ sprintf (op, "#%d", dst);
6144
+ sprintf (comm, "#0x%05x", dst & 0xfffff);
6146
+ case OP_20BIT_HEX:
6147
+ sprintf (op, "#0x%05x", dst & 0xfffff);
6149
+ default: // #n in rxxm
6150
+ sprintf (op, "#%d", dst);
6154
+ case 2: // constant #8
6155
+ sprintf (op, "#8");
6156
+ sprintf (comm, "r2 As==11");
6158
+ case 3: // constant #-1
6159
+ sprintf (op, "#-1");
6160
+ sprintf (comm, "r3 As==11");
6163
+ sprintf (op, "@r%d+", reg);
6171
-msp430_nooperands (struct msp430_opcode_s *opcode,
6172
+msp430_nooperands (struct msp430_opcode_s const *opcode,
6173
bfd_vma addr ATTRIBUTE_UNUSED,
6174
unsigned short insn ATTRIBUTE_UNUSED,
6179
/* Pop with constant. */
6181
@@ -65,18 +206,16 @@ msp430_nooperands (struct msp430_opcode_s *opcode,
6182
if (insn == opcode->bin_opcode)
6185
- if (opcode->fmt == 0)
6186
+ if (opcode_format(opcode) == FMT_EMULATED)
6188
if ((insn & 0x0f00) != 3 || (insn & 0x0f00) != 2)
6191
strcpy (comm, "emulated...");
6196
strcpy (comm, "return from interupt");
6201
@@ -84,16 +223,14 @@ msp430_nooperands (struct msp430_opcode_s *opcode,
6204
msp430_singleoperand (disassemble_info *info,
6205
- struct msp430_opcode_s *opcode,
6206
+ struct msp430_opcode_s const *opcode,
6208
unsigned short insn,
6214
int regs = 0, regd = 0;
6220
@@ -102,9 +239,9 @@ msp430_singleoperand (disassemble_info *info,
6221
as = (insn & 0x0030) >> 4;
6222
ad = (insn & 0x0080) >> 7;
6224
- switch (opcode->fmt)
6225
+ switch (opcode_format(opcode))
6227
- case 0: /* Emulated work with dst register. */
6228
+ case FMT_EMULATED: /* Emulated work with dst register. */
6229
if (regs != 2 && regs != 3 && regs != 1)
6232
@@ -116,167 +253,23 @@ msp430_singleoperand (disassemble_info *info,
6233
if ((opcode->bin_opcode & 0xff00) == 0x5300 && as == 3)
6244
- sprintf (op, "r0");
6246
- else if (regd == 1)
6247
- sprintf (op, "r1");
6249
- else if (regd == 2)
6250
- sprintf (op, "r2");
6253
- sprintf (op, "r%d", regd);
6255
- else /* ad == 1 msp430dis_opcode. */
6259
- /* PC relative. */
6260
- dst = msp430dis_opcode (addr + 2, info);
6263
- sprintf (op, "0x%04x", dst);
6264
- sprintf (comm, "PC rel. abs addr 0x%04x",
6265
- PS ((short) (addr + 2) + dst));
6267
- else if (regd == 2)
6270
- dst = msp430dis_opcode (addr + 2, info);
6273
- sprintf (op, "&0x%04x", PS (dst));
6277
- dst = msp430dis_opcode (addr + 2, info);
6280
- sprintf (op, "%d(r%d)", dst, regd);
6283
+ dst = msp430dis_operand (addr + cmd_len, info, regd, ad, &cmd_len);
6284
+ msp430x_decode_operand (regd, ad, addr + cmd_len, dst, OP_16BIT, op, comm);
6287
- case 2: /* rrc, push, call, swpb, rra, sxt, push, call, reti etc... */
6293
- sprintf (op, "#0");
6294
- sprintf (comm, "r3 As==00");
6299
- sprintf (op, "r%d", regd);
6308
- sprintf (op, "#4");
6309
- sprintf (comm, "r2 As==10");
6311
- else if (regd == 3)
6313
- sprintf (op, "#2");
6314
- sprintf (comm, "r3 As==10");
6319
- /* Indexed register mode @Rn. */
6320
- sprintf (op, "@r%d", regd);
6328
- sprintf (op, "#8");
6329
- sprintf (comm, "r2 As==11");
6331
- else if (regd == 3)
6333
- sprintf (op, "#-1");
6334
- sprintf (comm, "r3 As==11");
6336
- else if (regd == 0)
6339
- /* absolute. @pc+ */
6340
- dst = msp430dis_opcode (addr + 2, info);
6342
- sprintf (op, "#%d", dst);
6343
- sprintf (comm, "#0x%04x", PS (dst));
6348
- sprintf (op, "@r%d+", regd);
6356
- /* PC relative. */
6357
- dst = msp430dis_opcode (addr + 2, info);
6359
- sprintf (op, "0x%04x", PS (dst));
6360
- sprintf (comm, "PC rel. 0x%04x",
6361
- PS ((short) addr + 2 + dst));
6363
- else if (regd == 2)
6366
- dst = msp430dis_opcode (addr + 2, info);
6368
- sprintf (op, "&0x%04x", PS (dst));
6370
- else if (regd == 3)
6373
- sprintf (op, "#1");
6374
- sprintf (comm, "r3 As==01");
6379
- dst = msp430dis_opcode (addr + 2, info);
6381
- sprintf (op, "%d(r%d)", dst, regd);
6384
+ case FMT_SINGLE_OPERAND: /* rrc, push, call, swpb, rra, sxt, push, call, reti etc... */
6385
+ dst = msp430dis_operand (addr + cmd_len, info, regd, as, &cmd_len);
6386
+ if(opcode_variant(opcode) != V_CALL)
6387
+ msp430x_decode_operand (regd, as, addr + cmd_len, dst, OP_16BIT, op, comm);
6389
+ msp430x_decode_operand (regd, as, addr + cmd_len, dst, OP_16BIT_HEX, op, comm);
6392
- case 3: /* Jumps. */
6393
- where = insn & 0x03ff;
6394
- if (where & 0x200)
6396
- if (where > 512 || where < -511)
6400
- sprintf (op, "$%+-8d", where + 2);
6401
- sprintf (comm, "abs 0x%x", PS ((short) (addr) + 2 + where));
6403
+ case FMT_JUMP: /* Jumps. */
6404
+ dst = (short)((insn & 0x03ff) << 6) >> 5; // sign extension, word addr to byte addr conversion
6405
+ sprintf (op, "$%+-8d", dst + 2);
6406
+ sprintf (comm, "abs 0x%x", PS ((short) (addr) + 2 + dst));
6412
@@ -286,26 +279,26 @@ msp430_singleoperand (disassemble_info *info,
6415
msp430_doubleoperand (disassemble_info *info,
6416
- struct msp430_opcode_s *opcode,
6417
+ struct msp430_opcode_s const *opcode,
6419
unsigned short insn,
6427
int regs = 0, regd = 0;
6435
regs = (insn & 0x0f00) >> 8;
6436
as = (insn & 0x0030) >> 4;
6437
ad = (insn & 0x0080) >> 7;
6439
- if (opcode->fmt == 0)
6440
+ if (opcode_format(opcode) == FMT_EMULATED)
6442
/* Special case: rla and rlc are the only 2 emulated instructions that
6443
fall into two operand instructions. */
6444
@@ -320,347 +313,354 @@ msp430_doubleoperand (disassemble_info *info,
6445
if (regd != regs || as != ad)
6446
return 0; /* May be 'data' section. */
6450
- /* Register mode. */
6453
- strcpy (comm1, _("Illegal as emulation instr"));
6457
- sprintf (op1, "r%d", regd);
6460
- else /* ad == 1 */
6461
+ if (ad == 0 && regd == 3) // #N
6465
- /* PC relative, Symbolic. */
6466
- dst = msp430dis_opcode (addr + 2, info);
6469
- sprintf (op1, "0x%04x", PS (dst));
6470
- sprintf (comm1, "PC rel. 0x%04x",
6471
- PS ((short) addr + 2 + dst));
6474
- else if (regd == 2)
6477
- dst = msp430dis_opcode (addr + 2, info);
6478
- /* If the 'src' field is not the same as the dst
6479
- then this is not an rla instruction. */
6480
- if (dst != msp430dis_opcode (addr + 4, info))
6484
- sprintf (op1, "&0x%04x", PS (dst));
6489
- dst = msp430dis_opcode (addr + 2, info);
6492
- sprintf (op1, "%d(r%d)", dst, regd);
6494
+ strcpy (comm1, _("Illegal as emulation instr"));
6497
+ ops = msp430dis_operand (addr + cmd_len, info, regs, as, &cmd_len);
6498
+ opd = msp430dis_operand (addr + cmd_len, info, regd, ad, &cmd_len);
6499
+ /* If the 'src' field is not the same as the dst
6500
+ then this is not an rla instruction. */
6503
+ msp430x_decode_operand (regs, as, addr + cmd_len, ops, OP_16BIT, op1, comm1);
6510
/* Two operands exactly. */
6512
if (ad == 0 && regd == 3)
6514
/* R2/R3 are illegal as dest: may be data section. */
6515
strcpy (comm1, _("Illegal as 2-op instr"));
6518
+ ops = msp430dis_operand (addr + cmd_len, info, regs, as, &cmd_len);
6519
+ msp430x_decode_operand (regs, as, addr + cmd_len, ops, OP_16BIT, op1, comm1);
6528
- sprintf (op1, "#0");
6529
- sprintf (comm1, "r3 As==00");
6534
- sprintf (op1, "r%d", regs);
6540
+ opd = msp430dis_operand (addr + cmd_len, info, regd, ad, &cmd_len);
6541
+ msp430x_decode_operand (regd, ad, addr + cmd_len, opd, OP_16BIT, op2, comm2);
6547
- sprintf (op1, "#4");
6548
- sprintf (comm1, "r2 As==10");
6550
- else if (regs == 3)
6552
- sprintf (op1, "#2");
6553
- sprintf (comm1, "r3 As==10");
6559
+msp430_branchinstr (disassemble_info *info,
6560
+ struct msp430_opcode_s const *opcode ATTRIBUTE_UNUSED,
6561
+ bfd_vma addr ATTRIBUTE_UNUSED,
6562
+ unsigned short insn,
6566
+ int regs = (insn & 0x0f00) >> 8;
6567
+ int as = (insn & 0x0030) >> 4;
6571
- /* Indexed register mode @Rn. */
6572
- sprintf (op1, "@r%d", regs);
6578
+ dst = msp430dis_operand (addr + cmd_len, info, regs, as, &cmd_len);
6579
+ msp430x_decode_operand(regs, as, addr + cmd_len, dst, OP_16BIT_HEX, op1, comm1);
6585
+msp430x_opwidth(unsigned int insn)
6587
+ insn &= NON_ADDR_OPERATION | BYTE_OPERATION_X;
6589
+ if(insn == (NON_ADDR_OPERATION | BYTE_OPERATION_X))
6591
+ if(insn == NON_ADDR_OPERATION)
6593
+ if(insn == BYTE_OPERATION_X)
6596
+ return 0; // reserved
6600
+msp430x_singleoperand (disassemble_info *info,
6601
+ struct msp430_opcode_s const *opcode,
6603
+ unsigned int insn,
6608
+ int reg = (insn >> 16) & 0xf;
6609
+ int am = (insn >> 20) & 0x3;
6613
+ if ( opcode_variant(opcode) < V_PUSHX )
6614
+ if ((am == 3 && reg == 0) // #N operand
6615
+ || (am == 0 && reg == 3) // R3 is illegal as dest: may be data section.
6618
+ strcpy (comm, _("Illegal as 1-op instr"));
6622
+ // extract repeat count if any
6623
+ if ( am == 0 ) // extension word for register mode
6627
- sprintf (op1, "#8");
6628
- sprintf (comm1, "r2 As==11");
6631
- else if (regs == 3)
6633
- sprintf (op1, "#-1");
6634
- sprintf (comm1, "r3 As==11");
6637
- else if (regs == 0)
6640
- /* Absolute. @pc+. */
6641
- dst = msp430dis_opcode (addr + 2, info);
6643
- sprintf (op1, "#%d", dst);
6644
- sprintf (comm1, "#0x%04x", PS (dst));
6649
- sprintf (op1, "@r%d+", regs);
6657
- /* PC relative. */
6658
- dst = msp430dis_opcode (addr + 2, info);
6660
- sprintf (op1, "0x%04x", PS (dst));
6661
- sprintf (comm1, "PC rel. 0x%04x",
6662
- PS ((short) addr + 2 + dst));
6664
- else if (regs == 2)
6668
- dst = msp430dis_opcode (addr + 2, info);
6670
- sprintf (op1, "&0x%04x", PS (dst));
6671
- sprintf (comm1, "0x%04x", PS (dst));
6673
- else if (regs == 3)
6676
- sprintf (op1, "#1");
6677
- sprintf (comm1, "r3 As==01");
6683
- dst = msp430dis_opcode (addr + 2, info);
6685
- sprintf (op1, "%d(r%d)", dst, regs);
6687
+ if (insn & 0x008f) // repetitions
6689
+ if (insn & 0x0080)
6690
+ *repeats = insn & 0xf; // positive number is Rn
6692
+ *repeats = 0 - (insn & 0xf); // negative number is #N
6696
- /* Destination. Special care needed on addr + XXXX. */
6697
+ // extract operands
6698
+ dst = msp430dis_operand(addr + cmd_len, info, reg, am, &cmd_len) | ((insn & 0x0000000f) << 16);
6699
+ dst = (dst << 12) >> 12; // sign extension
6700
+ msp430x_decode_operand(reg, am, addr + cmd_len, dst, OP_20BIT, op, comm);
6706
+msp430x_exception (disassemble_info *info,
6707
+ struct msp430_opcode_s const *opcode,
6709
+ unsigned int insn,
6714
+ opwidth_t *op_width)
6724
+ switch(opcode_variant(opcode))
6730
- sprintf (op2, "r0");
6732
- else if (regd == 1)
6733
- sprintf (op2, "r1");
6735
+ switch((insn >> 4) & 0xf)
6738
+ msp430x_decode_operand(reg, 0, 0, 0, 0, op1, comm1);
6740
+ case 5: // x(Rdst)
6741
+ dst = (short)msp430dis_operand(addr + cmd_len, info, reg, 1, &cmd_len);
6742
+ msp430x_decode_operand(reg, 1, addr + cmd_len, dst, OP_16BIT, op1, comm1);
6745
+ msp430x_decode_operand(reg, 2, 0, 0, 0, op1, comm1);
6748
+ msp430x_decode_operand(reg, 3, 0, 0, 0, op1, comm1);
6751
+ dst = msp430dis_operand(addr + cmd_len, info, 2, 1, &cmd_len) | ((insn & 0x000f) << 16);
6752
+ msp430x_decode_operand(2, 1, addr + cmd_len, dst, OP_20BIT_HEX, op1, comm1);
6755
+ dst = msp430dis_operand(addr + cmd_len, info, 0, 1, &cmd_len) | ((insn & 0x000f) << 16);
6756
+ msp430x_decode_operand(0, 1, addr + cmd_len, dst, OP_20BIT, op1, comm1);
6758
+ case 0xb: // #imm20
6759
+ dst = msp430dis_operand(addr + cmd_len, info, 0, 3, &cmd_len) | ((insn & 0x000f) << 16);
6760
+ msp430x_decode_operand(0, 3, addr + cmd_len, dst, OP_20BIT_HEX, op1, comm1);
6765
+ n = ((insn >> 4) & 0xf) + 1;
6766
+ msp430x_decode_operand(0, 3, 0, n, OP_DECIMAL, op1, comm1); // #N
6767
+ msp430x_decode_operand(reg, 0, 0, 0, 0, op2, comm2); // Rdst
6768
+ if ((insn & 0x0100) == 0)
6769
+ *op_width = ADDR_OP;
6772
+ n = ((insn >> 4) & 0xf) + 1;
6773
+ reg = (reg + n - 1) & 0xf;
6774
+ msp430x_decode_operand(0, 3, 0, n, OP_DECIMAL, op1, comm1); // #N
6775
+ msp430x_decode_operand(reg, 0, 0, 0, 0, op2, comm2); // Rdst
6776
+ if ((insn & 0x0100) == 0)
6777
+ *op_width = ADDR_OP;
6780
+ n = ((insn >> 10) & 0x3) + 1;
6781
+ msp430x_decode_operand(0, 3, 0, n, OP_DECIMAL, op1, comm1); // #N
6782
+ msp430x_decode_operand(reg, 0, 0, 0, 0, op2, comm2); // Rdst
6783
+ if ((insn & 0x0010) == 0)
6784
+ *op_width = ADDR_OP;
6793
+msp430x_doubleoperand (disassemble_info *info,
6794
+ struct msp430_opcode_s const *opcode,
6796
+ unsigned int insn,
6801
+ opwidth_t *op_width,
6809
- else if (regd == 2)
6810
- sprintf (op2, "r2");
6811
+ regd = (insn >> 16) & 0xf;
6812
+ regs = (insn >> 24) & 0xf;
6813
+ as = (insn >> 20) & 0x3;
6814
+ ad = (insn >> 23) & 0x1;
6817
- sprintf (op2, "r%d", regd);
6818
+ if (ad == 0 && regd == 3)
6820
+ // R3 is illegal as dest: may be data section.
6822
+ strcpy (comm1, _("Illegal as 2-op instr"));
6824
+ strcpy (comm2, _("Illegal as 2-op instr"));
6827
- else /* ad == 1. */
6828
+ *op_width = msp430x_opwidth(insn);
6830
+ // extract repeat count if any
6831
+ if ( as == 0 && ad == 0 ) // extension word for register mode
6837
- /* PC relative. */
6839
- dst = msp430dis_opcode (addr + cmd_len, info);
6840
- sprintf (op2, "0x%04x", PS (dst));
6841
- sprintf (comm2, "PC rel. 0x%04x",
6842
- PS ((short) addr + cmd_len + dst));
6845
- else if (regd == 2)
6848
- dst = msp430dis_opcode (addr + cmd_len, info);
6850
- sprintf (op2, "&0x%04x", PS (dst));
6854
- dst = msp430dis_opcode (addr + cmd_len, info);
6856
- sprintf (op2, "%d(r%d)", dst, regd);
6858
+ if (insn & 0x008f) // repetitions
6860
+ if (insn & 0x0080)
6861
+ *repeats = insn & 0xf; // positive number is Rn
6863
+ *repeats = 0 - (insn & 0xf); // negative number is #N
6866
+ // extract operands
6867
+ ops = msp430dis_operand(addr + cmd_len, info, regs, as, &cmd_len) | ((insn & 0x00000780) << 9);
6868
+ ops = (ops << 12) >> 12; // sign extension
6869
+ msp430x_decode_operand(regs, as, addr + cmd_len, ops, OP_20BIT, op1, comm1);
6871
+ opd = msp430dis_operand(addr + cmd_len, info, regd, ad, &cmd_len) | ((insn & 0x0000000f) << 16);
6872
+ opd = (opd << 12) >> 12; // sign extension
6873
+ if (opcode_variant(opcode) == V_X_SHIFT
6874
+ && ((0 == (as | ad) && ops != opd) /* non-register extension different ops */
6875
+ || regs != regd)) /* register extension different regs */
6876
+ return 0; // different operand => not emulated shift
6878
+ msp430x_decode_operand(regd, ad, addr + cmd_len, opd, OP_20BIT, op2, comm2);
6884
-msp430_branchinstr (disassemble_info *info,
6885
- struct msp430_opcode_s *opcode ATTRIBUTE_UNUSED,
6886
- bfd_vma addr ATTRIBUTE_UNUSED,
6887
+msp430x_address (disassemble_info *info,
6889
unsigned short insn,
6896
- int regs = 0, regd = 0;
6901
- regd = insn & 0x0f;
6902
- regs = (insn & 0x0f00) >> 8;
6903
- as = (insn & 0x0030) >> 4;
6905
- if (regd != 0) /* Destination register is not a PC. */
6908
- /* dst is a source register. */
6917
- sprintf (op1, "#0");
6918
- sprintf (comm1, "r3 As==00");
6924
- sprintf (op1, "r%d", regs);
6933
+ static operands_t const operands_table[] =
6938
- sprintf (op1, "#4");
6939
- sprintf (comm1, "r2 As==10");
6941
- else if (regs == 3)
6944
- sprintf (op1, "#2");
6945
- sprintf (comm1, "r3 As==10");
6949
- /* Indexed register mode @Rn. */
6951
- sprintf (op1, "@r%d", regs);
6955
+ { 2, -1, 0, -1, 0 }, // 0 @Rsrc, Rdst
6956
+ { 3, -1, 0, -1, 0 }, // 1 @Rsrc+, Rdst
6957
+ { 1, 2, 0, -1, 2 }, // 2 &abs20, Rdst
6958
+ { 1, -1, 0, -1, 2 }, // 3 x(Rsrc), Rdst
6959
+ { 0, 0, 0, 0, 0 }, // 4
6960
+ { 0, 0, 0, 0, 0 }, // 5
6961
+ { 0, -1, 1, 2, 2 }, // 6 Rsrc, &abs20
6962
+ { 0, -1, 1, -1, 2 }, // 7 Rsrc, x(Rdst)
6963
+ { 3, 0, 0, -1, 2 }, // 8 #imm20, Rdst
6964
+ { 3, 0, 0, -1, 2 }, // 9 #imm20, Rdst
6965
+ { 3, 0, 0, -1, 2 }, // a #imm20, Rdst
6966
+ { 3, 0, 0, -1, 2 }, // b #imm20, Rdst
6967
+ { 0, -1, 0, -1, 0 }, // c Rsrc, Rdst
6968
+ { 0, -1, 0, -1, 0 }, // d Rsrc, Rdst
6969
+ { 0, -1, 0, -1, 0 }, // e Rsrc, Rdst
6970
+ { 0, -1, 0, -1, 0 }, // f Rsrc, Rdst
6973
+ operands_t operands = operands_table[(insn >> 4) & 0xf];
6974
+ if(((insn >> 4) & 0xf) == 6)
6975
+ dst = msp430dis_opcode (addr + cmd_len, info) | ((insn & 0x000f) << 16);
6976
+ else if(((insn >> 4) & 0xb) == 3)
6977
+ dst = (short)msp430dis_opcode (addr + cmd_len, info);
6978
+ else if(operands.length != 0)
6979
+ dst = msp430dis_opcode(addr + cmd_len, info) | ((insn & 0x0f00) << 8);
6981
+ if(operands.regs == -1)
6982
+ operands.regs = (insn >> 8 ) & 0x000f;
6983
+ if(operands.regd == -1)
6984
+ operands.regd = (insn >> 0 ) & 0x000f;
6986
+ if (operands.regd == 3)
6991
- sprintf (op1, "#8");
6992
- sprintf (comm1, "r2 As==11");
6994
- else if (regs == 3)
6997
- sprintf (op1, "#-1");
6998
- sprintf (comm1, "r3 As==11");
7000
- else if (regs == 0)
7002
- /* Absolute. @pc+ */
7004
- dst = msp430dis_opcode (addr + 2, info);
7006
- sprintf (op1, "#0x%04x", PS (dst));
7011
- sprintf (op1, "@r%d+", regs);
7013
+ // R3 is illegal as dest: may be data section.
7015
+ strcpy (comm1, _("Illegal as address instr"));
7017
+ strcpy (comm2, _("Illegal as address instr"));
7023
+ // extract operands
7024
+ msp430x_decode_operand(operands.regs, operands.as, addr + cmd_len, dst,
7025
+ ((insn >> 4) & 0xf) == 3 ? OP_16BIT_HEX : OP_20BIT_HEX, op1, comm1);
7026
+ msp430x_decode_operand(operands.regd, operands.ad, addr + cmd_len, dst,
7027
+ ((insn >> 4) & 0xf) == 7 ? OP_16BIT_HEX : OP_20BIT_HEX, op2, comm2);
7028
+ return cmd_len + operands.length;
7033
- /* PC relative. */
7034
- dst = msp430dis_opcode (addr + 2, info);
7037
- sprintf (op1, "0x%04x", PS (dst));
7038
- sprintf (comm1, "PC rel. 0x%04x",
7039
- PS ((short) addr + 2 + dst));
7041
- else if (regs == 2)
7044
- dst = msp430dis_opcode (addr + 2, info);
7046
- sprintf (op1, "&0x%04x", PS (dst));
7048
- else if (regs == 3)
7051
- sprintf (op1, "#1");
7052
- sprintf (comm1, "r3 As==01");
7057
- dst = msp430dis_opcode (addr + 2, info);
7059
- sprintf (op1, "%d(r%d)", dst, regs);
7063
+msp430x_emulated (disassemble_info *info,
7064
+ struct msp430_opcode_s const *opcode,
7066
+ unsigned int insn,
7069
+ opwidth_t *op_width,
7074
+ switch(opcode_variant(opcode))
7078
+ // emulated by double operand instruction
7079
+ return msp430x_doubleoperand(info, opcode, addr, insn, (char *)0, op1,
7080
+ (char *)0, comm1, op_width, repeats);
7081
+ case V_RETA: // reta, substituted by mova
7083
+ case V_EMU_ADDR: // substituted by other address instruction
7084
+ return msp430x_address(info, addr, insn, (char *)0, op1,
7085
+ (char *)0, comm1);
7086
+ case V_BRA: // bra, substituted by mova
7087
+ return msp430x_address(info, addr, insn, op1, (char *)0,
7088
+ comm1, (char *)0);
7096
@@ -668,22 +668,32 @@ print_insn_msp430 (bfd_vma addr, disassemble_info *info)
7098
void *stream = info->stream;
7099
fprintf_ftype prin = info->fprintf_func;
7100
- struct msp430_opcode_s *opcode;
7101
+ struct msp430_opcode_s const *opcode;
7102
char op1[32], op2[32], comm1[64], comm2[64];
7104
- unsigned short insn;
7107
- char dinfo[32]; /* Debug purposes. */
7109
+ unsigned int insn;
7111
+ int cpu = (bfd_mach_msp430x == info->mach) ? MSP430_CPU_MSP430X : MSP430_CPU_MSP430;
7113
+ opwidth_t op_width = DEFAULT_OP; // word instruction by default
7114
+ static char const *width_modifier[] =
7115
+ {"", "", ".b", ".a" };
7117
insn = msp430dis_opcode (addr, info);
7118
- sprintf (dinfo, "0x%04x", insn);
7120
- if (((int) addr & 0xffff) > 0xffdf)
7122
+ if ( (core == CORE_430 && ((int) addr & 0xffff) >= 0xffe0)
7123
+ || ( core == CORE_430X && (((int) addr & 0xfffff) >= 0xffc0) && ((int) addr & 0xfffff) < 0x10000)
7124
+ || ( core == CORE_430X2 && (((int) addr & 0xfffff) >= 0xff80) && ((int) addr & 0xfffff) < 0x10000)
7127
(*prin) (stream, "interrupt service routine at 0x%04x", 0xffff & insn);
7132
+ if (cpu >= MSP430_CPU_MSP430X && ((insn & 0xf800) == 0x1800)) // Extended instruction
7133
+ insn |= msp430dis_opcode(addr + 2, info) << 16;
7137
@@ -691,62 +701,107 @@ print_insn_msp430 (bfd_vma addr, disassemble_info *info)
7138
for (opcode = msp430_opcodes; opcode->name; opcode++)
7140
if ((insn & opcode->bin_mask) == opcode->bin_opcode
7141
- && opcode->bin_opcode != 0x9300)
7142
+// && opcode->bin_opcode != 0x9300 // was disasm tst instruction as cmp #0, dst?
7150
- /* r0 as destination. Ad should be zero. */
7151
- if (opcode->insn_opnumb == 3 && (insn & 0x000f) == 0
7152
- && (0x0080 & insn) == 0)
7153
+ /* unsupported instruction */
7154
+ if(opcode_format(opcode) >= FMT_X && cpu < MSP430_CPU_MSP430X)
7157
+ /* r0 as destination. Ad should be zero. Rdst=0 and Ad=0 are encoded in opcode & opcode_mask */
7158
+ if (opcode_format(opcode) == FMT_EMULATED && opcode_variant(opcode) == V_BR)
7161
- msp430_branchinstr (info, opcode, addr, insn, op1, comm1,
7163
+ msp430_branchinstr (info, opcode, addr, insn, op1, comm1);
7168
- switch (opcode->insn_opnumb)
7171
- cmd_len = msp430_nooperands (opcode, addr, insn, comm1, &cycles);
7175
- msp430_doubleoperand (info, opcode, addr, insn, op1, op2,
7176
- comm1, comm2, &cycles);
7177
- if (insn & BYTE_OPERATION)
7182
- msp430_singleoperand (info, opcode, addr, insn, op1, comm1,
7184
- if (insn & BYTE_OPERATION && opcode->fmt != 3)
7190
+ if(opcode_format(opcode) < FMT_X)
7191
+ switch (opcode->insn_opnumb)
7194
+ cmd_len = msp430_nooperands (opcode, addr, insn, comm1);
7198
+ msp430_doubleoperand (info, opcode, addr, insn, op1, op2,
7200
+ if (insn & BYTE_OPERATION)
7201
+ op_width = BYTE_OP;
7205
+ msp430_singleoperand (info, opcode, addr, insn, op1, comm1);
7206
+ if (insn & BYTE_OPERATION && opcode_format(opcode) != FMT_JUMP)
7207
+ op_width = BYTE_OP;
7212
+ else // 430x instruction
7213
+ switch(opcode_format(opcode))
7215
+ case FMT_X_SINGLE_OPERAND:
7216
+ if( opcode_variant(opcode) == V_SWPSXT // swpbx, sxtx
7217
+ && (insn & (NON_ADDR_OPERATION | BYTE_OPERATION_X)) == 0) // .a, special case
7218
+ insn ^= BYTE_OPERATION_X; // make A/L, B/W as ordinary
7220
+ op_width = msp430x_opwidth(insn);
7222
+ if( opcode_variant(opcode) == V_SWPSXT && op_width == BYTE_OP) // swpbx, sxtx
7223
+ strcpy (comm1, _("Illegal A/L, B/W bits setting"));
7225
+ cmd_len = msp430x_singleoperand (info, opcode, addr, insn, op1, comm1,
7228
+ case FMT_X_EXCEPTION:
7229
+ cmd_len = msp430x_exception (info, opcode, addr, insn, op1, op2,
7230
+ comm1, comm2, &op_width);
7232
+ case FMT_X_DOUBLE_OPERAND:
7233
+ cmd_len = msp430x_doubleoperand (info, opcode, addr, insn, op1, op2,
7234
+ comm1, comm2, &op_width, &repeats);
7236
+ case FMT_X_EMULATED:
7237
+ cmd_len = msp430x_emulated (info, opcode, addr, insn, op1,
7238
+ comm1, &op_width, &repeats);
7241
+ case FMT_X_ADDRESS:
7242
+ cmd_len = msp430x_address (info, addr, insn, op1, op2,
7258
/* Unknown opcode, or invalid combination of operands. */
7259
- (*prin) (stream, ".word 0x%04x; ????", PS (insn));
7260
+ (*prin) (stream, ".word 0x%04x; ????\t%s%s", PS (insn), comm1, comm2);
7264
- (*prin) (stream, "%s%s", opcode->name, bc);
7269
+ (*prin) (stream, ".rpt\t#%d\n\t\t\t\t", 0 - repeats);
7271
+ (*prin) (stream, ".rpt\tr%d\n\t\t\t\t", repeats);
7274
+ (*prin) (stream, "%s%s", opcode->name, width_modifier[op_width]);
7277
(*prin) (stream, "\t%s", op1);
7278
@@ -765,23 +820,11 @@ print_insn_msp430 (bfd_vma addr, disassemble_info *info)
7280
if (*comm1 || *comm2)
7281
(*prin) (stream, ";");
7285
- (*prin) (stream, ";");
7288
- if (strlen (op1) < 7)
7289
- (*prin) (stream, ";");
7291
- (*prin) (stream, "\t;");
7295
(*prin) (stream, "%s", comm1);
7296
if (*comm1 && *comm2)
7297
- (*prin) (stream, ",");
7298
+ (*prin) (stream, ", ");
7300
- (*prin) (stream, " %s", comm2);
7301
+ (*prin) (stream, "%s", comm2);