Skip to content

Commit d0d91b6

Browse files
committed
[TMS32010] Refactor to support TMS3202x variants
1 parent 4c1d4d6 commit d0d91b6

14 files changed

+320
-237
lines changed

src/Makefile.arch

+1-1
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ S19_OUTS = $(TGT_mc6809) $(TGT_mc6800) $(TGT_mc6805) mos6502 g65sc02 r65c02 w65c
149149
# targets with Motorola S28 format
150150
S28_OUTS = $(TGT_mc68000) m68k w65c816 w65c816_m0x0 w65c816_m0x1 w65c816_m1x0 w65c816_m1x1
151151
# targets with Intel32 (32bit address) format
152-
I32_OUTS = z8001 z8k1 ns32032 ns32k mn1613
152+
I32_OUTS = z8001 z8k1 ns32032 ns32k mn1613 tms320c25 tms320c26
153153
# other targets use Intel8 format
154154
define __out-ext # target
155155
$(if $(filter $(1),$(S19_OUTS)),s19,$(if $(filter $(1),$(S28_OUTS)),s28,hex))

src/asm_tms32010.cpp

+57-46
Original file line numberDiff line numberDiff line change
@@ -57,29 +57,9 @@ AsmTms32010::AsmTms32010(const ValueParser::Plugins &plugins)
5757
reset();
5858
}
5959

60-
namespace {
61-
62-
AddrMode constantType(uint16_t val) {
63-
if (val == 0)
64-
return M_LS0;
65-
if (val == 1)
66-
return M_DPK;
67-
if (val == 4)
68-
return M_LS3;
69-
if (val < 8)
70-
return M_IM3;
71-
if (val < 16)
72-
return M_LS4;
73-
if (val < 0x100)
74-
return M_IM8;
75-
return M_IM13;
76-
}
77-
78-
} // namespace
79-
8060
void AsmTms32010::encodeOperand(AsmInsn &insn, const Operand &op, AddrMode mode) const {
8161
insn.setErrorIf(op);
82-
static constexpr Config::opcode_t SST = 0x7C00;
62+
auto val = op.val.getUnsigned();
8363
switch (mode) {
8464
case M_MAM:
8565
switch (op.mode) {
@@ -93,44 +73,80 @@ void AsmTms32010::encodeOperand(AsmInsn &insn, const Operand &op, AddrMode mode)
9373
insn.embed(0x98);
9474
break;
9575
default:
96-
if (op.val.getUnsigned() > dataMemoryLimit())
97-
insn.setErrorIf(op, OVERFLOW_RANGE);
98-
if (insn.opCode() == SST && op.val.getUnsigned() < 0x80)
76+
if (!validDmAddr(insn.opCode(), val))
9977
insn.setErrorIf(op, OVERFLOW_RANGE);
100-
insn.embed(op.val.getUnsigned() & 0x7F);
78+
insn.embed(val & 0x7F);
10179
break;
10280
}
10381
break;
82+
case M_LS0:
83+
if (val)
84+
insn.setErrorIf(op, ILLEGAL_CONSTANT);
85+
break;
10486
case M_LS3:
105-
case M_LS4:
87+
if (!(val == 0 || val == 1 || val == 4))
88+
insn.setErrorIf(op, ILLEGAL_CONSTANT);
89+
// Fall-through
10690
case M_PA:
107-
insn.embed(op.val.getUnsigned() << 8);
91+
if (!isPA(decodePA(val))) {
92+
val &= maxPA();
93+
insn.setErrorIf(op, OVERFLOW_RANGE);
94+
}
95+
// Fall-through
96+
case M_LS4:
97+
if (op.val.overflow(15)) {
98+
val &= 15;
99+
insn.setErrorIf(op, OVERFLOW_RANGE);
100+
}
101+
insn.embed(val << 8);
108102
break;
109103
case M_NARP:
110-
if (op.mode == M_NONE)
111-
break;
112-
insn.setOpCode(insn.opCode() & ~8);
113-
insn.embed(op.val.getUnsigned());
104+
if (op.mode != M_NONE) {
105+
if (!isAR(decodeAR(val))) {
106+
val &= maxAR();
107+
insn.setErrorIf(op, UNKNOWN_REGISTER);
108+
}
109+
insn.setOpCode(insn.opCode() & ~8);
110+
insn.embed(val);
111+
}
114112
break;
115113
case M_AR:
116-
insn.embed(op.val.getUnsigned() << 8);
114+
if (!isAR(decodeAR(val))) {
115+
val &= maxAR();
116+
insn.setErrorIf(op, UNKNOWN_REGISTER);
117+
}
118+
insn.embed(val << 8);
117119
break;
118120
case M_ARK:
119-
case M_DPK:
120-
insn.embed(op.val.getUnsigned());
121+
if (!isAR(decodeAR(val))) {
122+
val &= maxAR();
123+
insn.setErrorIf(op, UNKNOWN_REGISTER);
124+
}
125+
insn.embed(val);
126+
break;
127+
case M_IM1:
128+
if (op.val.overflow(1)) {
129+
val &= 1;
130+
insn.setErrorIf(op, OVERFLOW_RANGE);
131+
}
132+
insn.embed(val);
121133
break;
122134
case M_IM8:
123-
insn.embed(op.val.getUnsigned());
135+
if (op.val.overflow(UINT8_MAX)) {
136+
val &= UINT8_MAX;
137+
insn.setErrorIf(op, OVERFLOW_RANGE);
138+
}
139+
insn.embed(val);
124140
break;
125141
case M_IM13:
126142
if (op.val.overflow(0x0FFF, -0x1000))
127143
insn.setErrorIf(op, OVERFLOW_RANGE);
128-
insn.embed(op.val.getUnsigned() & 0x1FFF);
144+
insn.embed(val & 0x1FFF);
129145
break;
130-
case M_PMA:
146+
case M_PM12:
131147
if (op.val.overflow(0x0FFF))
132148
insn.setErrorIf(op, OVERFLOW_RANGE);
133-
insn.emitOperand16(op.val.getUnsigned() & 0x0FFF);
149+
insn.emitOperand16(val & 0x0FFF);
134150
break;
135151
default:
136152
break;
@@ -156,21 +172,16 @@ Error AsmTms32010::parseOperand(StrScanner &scan, Operand &op) const {
156172
}
157173
op.reg = parseRegName(p);
158174
if (op.reg != REG_UNDEF) {
159-
if (isAuxiliary(op.reg)) {
160-
op.mode = M_AR;
161-
op.val.setUnsigned(int8_t(op.reg) - int8_t(REG_AR0));
162-
} else {
163-
op.mode = M_PA;
164-
op.val.setUnsigned(int8_t(op.reg) - int8_t(REG_PA0));
165-
}
175+
op.mode = isAR(op.reg) ? M_AR : M_PA;
176+
op.val.setUnsigned(encodeRegName(op.reg));
166177
scan = p;
167178
return OK;
168179
}
169180

170181
op.val = parseInteger(p, op);
171182
if (op.hasError())
172183
return op.getError();
173-
op.mode = constantType(op.val.getUnsigned());
184+
op.mode = M_CNST;
174185
scan = p;
175186
return OK;
176187
}

src/config_tms32010.h

+36-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#define __LIBASM_CONFIG_TMS32010_H__
1919

2020
#include "config_base.h"
21+
#include "reg_tms32010.h"
2122

2223
namespace libasm {
2324
namespace tms32010 {
@@ -31,9 +32,42 @@ struct Config
3132
: ConfigImpl<CpuType, ADDRESS_12BIT, ADDRESS_WORD, OPCODE_16BIT, ENDIAN_LITTLE, 4, 4> {
3233
Config(const InsnTable<CpuType> &table) : ConfigImpl(table, TMS32010) {}
3334

34-
uint16_t dataMemoryLimit() const {
35-
return cpuType() == TMS32010 ? 0x8F : 0xFF;
35+
protected:
36+
uint16_t dataMemoryMax() const { return cpuType() == TMS32010 ? UINT16_C(0x8F) : PAGE1_MAX; }
37+
38+
uint_fast8_t maxAR() const { return 1; }
39+
uint_fast8_t maxPA() const { return 7; }
40+
bool isAR(RegName name) const { return name >= REG_AR0 && name <= REG_AR0 + maxAR(); }
41+
bool isPA(RegName name) const { return name >= REG_PA0 && name <= REG_PA0 + maxPA(); }
42+
RegName decodeAR(uint32_t r) const { return r <= maxAR() ? RegName(r + REG_AR0) : REG_UNDEF; }
43+
RegName decodePA(uint32_t r) const { return r <= maxPA() ? RegName(r + REG_PA0) : REG_UNDEF; }
44+
45+
bool isSST(opcode_t opc) const {
46+
opc >>= 8;
47+
return opc == 0x7C; // SST
48+
}
49+
50+
bool validDmAddr(opcode_t opc, uint32_t dma) const {
51+
uint16_t min = UINT16_C(0);
52+
uint16_t max = dataMemoryMax();
53+
if (isSST(opc)) {
54+
// TMS3201x: SST destination must be in page 1.
55+
min = PAGE1_MIN;
56+
}
57+
return dma >= min && dma <= max;
3658
}
59+
60+
uint16_t toDmAddr(opcode_t opc) const {
61+
auto dma = opc & 0x7F;
62+
if (isSST(opc)) {
63+
// TMS3201x: SST destination must be in page 1.
64+
return PAGE1_MIN + dma;
65+
}
66+
return dma;
67+
}
68+
69+
static constexpr auto PAGE1_MIN = UINT16_C(0x0080);
70+
static constexpr auto PAGE1_MAX = UINT16_C(0x00FF);
3771
};
3872

3973
} // namespace tms32010

src/dis_tms32010.cpp

+38-29
Original file line numberDiff line numberDiff line change
@@ -41,43 +41,52 @@ DisTms32010::DisTms32010(const ValueFormatter::Plugins &plugins)
4141
}
4242

4343
StrBuffer &DisTms32010::outDirect(StrBuffer &out, DisInsn &insn) const {
44-
// Store Status Register can access Data Page 1 only.
45-
static constexpr uint8_t SST = 0x7C;
46-
const auto opc = insn.opCode();
47-
uint8_t dma = opc & 0x7F;
48-
if ((opc >> 8) == SST) {
49-
dma |= (1 << 7);
50-
if (dma > dataMemoryLimit())
51-
insn.setErrorIf(out, OVERFLOW_RANGE);
52-
}
44+
const auto dma = toDmAddr(insn.opCode());
45+
if (!validDmAddr(insn.opCode(), dma))
46+
insn.setErrorIf(out, OVERFLOW_RANGE);
5347
outAbsAddr(out, dma, 8);
5448
return out;
5549
}
5650

5751
StrBuffer &DisTms32010::outIndirect(StrBuffer &out, uint8_t mam) const {
52+
const auto modify = (mam >> 4) & 7;
5853
out.letter('*');
59-
if (mam & 0x20)
60-
return out.letter('+');
61-
if (mam & 0x10)
54+
if (modify == 4 || modify == 7)
55+
out.text_P(PSTR("BR0"));
56+
if (modify == 5 || modify == 6)
57+
out.letter('0');
58+
if (modify == 1 || modify == 4 || modify == 5)
6259
return out.letter('-');
60+
if (modify == 2 || modify == 6 || modify == 7)
61+
return out.letter('+');
6362
return out;
6463
}
6564

65+
StrBuffer &DisTms32010::outModifyAR(StrBuffer &out, uint8_t mam) const {
66+
const auto modify = (mam >> 4) & 7;
67+
if (modify)
68+
out.comma();
69+
return modify == 0 ? out : outIndirect(out, mam);
70+
}
71+
72+
namespace {
73+
bool hasNarp(uint_fast8_t mam) {
74+
if ((mam & 0x80) == 0)
75+
return false;
76+
const auto narp = mam & 8;
77+
return narp == 0;
78+
}
79+
} // namespace
80+
6681
StrBuffer &DisTms32010::outNextArp(StrBuffer &out, uint8_t mam) const {
67-
if ((mam & 0x80) && (mam & 8) == 0) {
68-
const RegName arp = (mam & 1) == 0 ? REG_AR0 : REG_AR1;
69-
outRegName(out.comma(), arp);
70-
}
82+
if (hasNarp(mam))
83+
outRegName(out.comma(), decodeAR(mam & maxAR()));
7184
return out;
7285
}
7386

7487
StrBuffer &DisTms32010::outShiftCount(StrBuffer &out, uint8_t count, uint8_t mam) const {
75-
const bool indir = mam & (1 << 7);
76-
const bool nar = (mam & (1 << 3)) == 0;
77-
if (count || (indir && nar)) {
78-
out.comma();
79-
outDec(out, count, 4);
80-
}
88+
if (count || hasNarp(mam))
89+
outDec(out.comma(), count, 4);
8190
return out;
8291
}
8392

@@ -89,10 +98,10 @@ StrBuffer &DisTms32010::outProgramAddress(StrBuffer &out, DisInsn &insn) const {
8998
}
9099

91100
void DisTms32010::decodeOperand(DisInsn &insn, StrBuffer &out, AddrMode mode) const {
92-
const Config::opcode_t opc = insn.opCode();
101+
const auto opc = insn.opCode();
93102
switch (mode) {
94103
case M_MAM:
95-
if (opc & (1 << 7)) {
104+
if (opc & 0x80) {
96105
outIndirect(out, opc);
97106
} else {
98107
outDirect(out, insn);
@@ -109,15 +118,15 @@ void DisTms32010::decodeOperand(DisInsn &insn, StrBuffer &out, AddrMode mode) co
109118
outShiftCount(out, (opc >> 8) & 7, opc);
110119
break;
111120
case M_AR:
112-
outRegName(out, (opc & (1 << 8)) == 0 ? REG_AR0 : REG_AR1);
121+
outRegName(out, decodeAR((opc >> 8) & maxAR()));
113122
break;
114123
case M_PA:
115-
outRegName(out, RegName(((opc >> 8) & 7) + int8_t(REG_PA0)));
124+
outRegName(out, decodePA((opc >> 8) & maxPA()));
116125
break;
117126
case M_ARK:
118-
outRegName(out, (opc & 1) == 0 ? REG_AR0 : REG_AR1);
127+
outRegName(out, decodeAR(opc & maxAR()));
119128
break;
120-
case M_DPK:
129+
case M_IM1:
121130
out.letter((opc & 1) == 0 ? '0' : '1');
122131
break;
123132
case M_IM8:
@@ -127,7 +136,7 @@ void DisTms32010::decodeOperand(DisInsn &insn, StrBuffer &out, AddrMode mode) co
127136
// Sign extends 13-bit number as 0x1000 is a sign bit.
128137
outDec(out, signExtend(opc, 13), -13);
129138
break;
130-
case M_PMA:
139+
case M_PM12:
131140
outProgramAddress(out, insn);
132141
break;
133142
default:

src/dis_tms32010.h

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ struct DisTms32010 final : Disassembler, Config {
3030
private:
3131
StrBuffer &outDirect(StrBuffer &out, DisInsn &insn) const;
3232
StrBuffer &outIndirect(StrBuffer &out, uint8_t mam) const;
33+
StrBuffer &outModifyAR(StrBuffer &out, uint8_t mam) const;
3334
StrBuffer &outNextArp(StrBuffer &out, uint8_t mam) const;
3435
StrBuffer &outShiftCount(StrBuffer &out, uint8_t count, uint8_t mam) const;
3536
StrBuffer &outProgramAddress(StrBuffer &out, DisInsn &insn) const;

src/entry_tms32010.h

+17-17
Original file line numberDiff line numberDiff line change
@@ -26,24 +26,24 @@ namespace libasm {
2626
namespace tms32010 {
2727

2828
enum AddrMode : uint8_t {
29-
// T=table, P=parser. Sorted by constant range from M_LS0 to M_IM13.
29+
// T=table, P=parser. M_IM1~M_CNST must be a constant.
3030
M_NONE = 0, // TP: No operand
31-
M_LS0 = 1, // TP: [0] 0 left shift (SACL) ---- -000 ---- ----
32-
M_DPK = 2, // TP: [0-1] Data memory page ---- ---- ---- ---d
33-
M_ARK = 3, // T_: [0-1] Auxiliary register ---- ---- ---- ---a
34-
M_AR = 4, // TP: AR[0-1] Auxiliary register ---- ---a ---- ----
35-
M_NARP = 5, // T_: AR[0-1] Next ARP ---- ---- 10id n00a
36-
M_LS3 = 6, // TP: [0-1,4] 3-bit left shift ---- -XXX ---- ----
37-
M_IM3 = 7, // _P: [0-7] 3-bit unsigned
38-
M_PA = 8, // TP: PA[0-7] Port Address ---- -AAA ---- ----
39-
M_LS4 = 9, // TP: [0-15] 4-bit left shift ---- SSSS ---- ----
40-
M_IM8 = 10, // TP: [0-255] 8-bit unsigned ---- ---- KKKK KKKK
41-
M_MAM = 11, // T_: [0-255] Memory addressing mode ---- ---- Immm mmmm
42-
M_PMA = 12, // TP: [0-4095] Program address ---- PPPP PPPP PPPP
43-
M_IM13 = 13, // TP: [-4096-4095] 13-bit signed ---K KKKK KKKK KKKK
44-
M_ARP = 14, // _P: "*" Indirect addressing
45-
M_INC = 15, // _P: "*+" Indirect then auto increment addressing
46-
M_DEC = 16, // _P: "*-" Indirect then auto decrement addressing
31+
M_IM1 = 1, // T_: 1-bit unsigned immediate ---- ---- ---- ---k
32+
M_IM8 = 3, // T_: 8-bit unsigned immediate ---- ---- kkkk kkkk
33+
M_IM13 = 5, // T_: 13-bit signed immediate ---k kkkk kkkk kkkk
34+
M_NARP = 7, // T_: Next ARP ---- ---- ---- xyyy
35+
M_ARK = 8, // T_: 3-bit AR register ---- ---- ---- -rrr
36+
M_AR = 9, // TP: AR[0-7] Auxiliary register ---- -rrr ---- ----
37+
M_PA = 10, // TP: PA[0-15] Port address ---- pppp ---- ----
38+
M_LS0 = 11, // T_: 0 constant for SACL ---- -000 ---- ----
39+
M_LS3 = 12, // T_: 3-bit left shift ---- -xxx ---- ----
40+
M_LS4 = 13, // T_: 4-bit left shift ---- ssss ---- ----
41+
M_PM12 = 15, // T_: 12-bit program address ---- pppp pppp pppp
42+
M_CNST = 17, // _P: constant
43+
M_MAM = 18, // T_: Direct address or M_IND ---- ---- ixxx xxxx
44+
M_ARP = 21, // _P: "*" Indirect addressing
45+
M_INC = 22, // _P: "*+" Indirect then auto increment addressing
46+
M_DEC = 23, // _P: "*-" Indirect then auto decrement addressing
4747
};
4848

4949
struct Entry final : entry::Base<Config::opcode_t> {

src/exract-common-text.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ function get_text {
66

77
function list_files {
88
for f in $(grep -lPow '(?<=^extern const char )'"$1" text_*.h); do
9-
printf "%-15s" $f
9+
printf "%-16s" $f
1010
done
1111
echo
1212
}

0 commit comments

Comments
 (0)