NASM 0.98p3
[nasm/avx512.git] / insns.bas
blob36dc3e127790fa6698ec18ba69387b60941e238b
1 ' INFO_1: Converter for INSNS.DAT to INSNSA.C and INSNSD.C
3 ' INFO_2: Written by Mark Junker in 1997
4 ' InterNet: mjs@prg.hannover.sgh-net.de
5 ' FIDO: Mark Junker@2:2437/47.21
7 ' COMMENT: While I wrote this program I often asked me, if it isn't easier
8 ' to write an interpreter for pearl-scripts :]
10 ' COMMENT: To start the program press SHIFT+F5 within the QBasic IDE
11 ' or start it from the command-line with QBASIC /RUN MACROS
14 DEFINT A-Z
16 DECLARE FUNCTION ReplaceOp$ (a$)
17 DECLARE FUNCTION StrTrimLeft$ (a$, b$)
18 DECLARE FUNCTION StrTrimRight$ (a$, b$)
19 DECLARE FUNCTION StrTrim$ (a$, b$)
20 DECLARE SUB StrSplitString (SplitString$, SplitChars$, SplitField$(), SplitCount%)
21 DECLARE FUNCTION Min% (a%, b%)
22 DECLARE FUNCTION StrInstrLeft% (SearchStart%, SearchIn$, SearchFor$)
23 DECLARE FUNCTION StrAscii% (a$)
26 CONST MaxOpCodeBase = 3
27 CONST MaxOpCodeType = 8
29 CLS
30 DIM LineData$(1 TO 2)
31 DIM StrucData$(1 TO 5)
32 DIM OpCodeList$(0 TO 255)
33 DIM OpCodeByte(1 TO MaxOpCodeType, 1 TO MaxOpCodeBase)
34 DIM OpCodeStat(1 TO 10) ' don't need mode :)
36 Instructs$ = ""
37 LineOfs$ = ""
39 OPEN "I", 1, "insns.dat"
40 OPEN "B", 3, "insns.tmp"
42 qt$ = CHR$(34)
43 crlf$ = CHR$(13) + CHR$(10)
47 ' preprocessing the current file
50 HexChar$ = "0123456789ABCDEF"
52 PRINT "Preprocessing INSNS.DAT"
53 OpCodes = 0
54 OpCodeDebug = 0
55 NowLineOfs& = 1
56 lineNr = 0
57 WHILE NOT EOF(1)
58 lineNr = lineNr + 1
59 IF (lineNr AND 15) = 0 THEN
60 LOCATE , 1
61 PRINT lineNr, OpCodes, OpCodeDebug;
62 END IF
64 LINE INPUT #1, l$
65 CALL StrSplitString(l$, ";", LineData$(), SplitCount)
66 IF SplitCount THEN
67 LineData$(1) = StrTrim$(LineData$(1), CHR$(9) + " ")
68 IF LEN(LineData$(1)) THEN
69 CALL StrSplitString(LineData$(1), " ", StrucData$(), cntSplit)
70 IF cntSplit <> 4 THEN
71 PRINT "line"; lineNr; " does not contain four fields"
72 END
73 END IF
75 tst$ = UCASE$(StrucData$(2))
76 res$ = ""
77 cnt% = 1
78 isfirst = 1
79 op = 1
80 p = StrInstrLeft(1, tst$ + ",", "|:,")
81 WHILE p
82 h$ = ReplaceOp$(MID$(tst$, op, p - op))
83 IF LEN(h$) THEN
84 SELECT CASE MID$(tst$, p, 1)
85 CASE ""
86 IF isfirst THEN
87 res$ = res$ + h$
88 ELSE
89 res$ = res$ + "|" + h$
90 END IF
91 isfirst = 0
92 CASE ","
93 IF isfirst THEN
94 res$ = res$ + h$ + ","
95 ELSE
96 res$ = res$ + "|" + h$ + ","
97 END IF
98 cnt% = cnt% + 1
99 isfirst = 1
100 CASE "|"
101 IF isfirst THEN
102 res$ = res$ + h$
103 ELSE
104 res$ = res$ + "|" + h$
105 END IF
106 isfirst = 0
107 CASE ":"
108 res$ = res$ + h$ + "|COLON,"
109 cnt% = cnt% + 1
110 END SELECT
111 END IF
112 op = p + 1
113 p = StrInstrLeft(op, tst$ + ",", "|:,")
114 WEND
115 FOR a = cnt% + 1 TO 3
116 res$ = res$ + ",0"
117 NEXT
118 StrucData$(2) = res$
119 IF LEFT$(res$, 2) = "0," THEN cnt% = cnt% - 1
120 StrucData$(5) = LTRIM$(STR$(cnt%))
122 NoDebug = 0
123 res$ = ""
124 tst$ = UCASE$(StrucData$(4))
125 op = 1
126 p = INSTR(tst$ + ",", ",")
127 isfirst = 1
128 WHILE p
129 h$ = MID$(tst$, op, p - op)
130 IF h$ = "ND" THEN
131 NoDebug = 1
132 ELSE
133 IF isfirst THEN
134 res$ = res$ + "IF_" + h$
135 ELSE
136 res$ = res$ + "|IF_" + h$
137 END IF
138 isfirst = 0
139 END IF
140 op = p + 1
141 p = INSTR(op, tst$ + ",", ",")
142 WEND
143 StrucData$(4) = res$
145 tst$ = UCASE$(StrucData$(3))
146 SELECT CASE tst$
147 CASE "IGNORE"
148 GOTO skipOpCode
149 CASE "\0", "\340"
150 OpCodeDebug = OpCodeDebug + 1 ' don't forget to increment
151 GOTO skipOpCode
152 END SELECT
154 AddRegs = 0
155 AddCCode = 0
156 NextIsOpCode = 0
157 opCodeVal$ = ""
158 op = 1
159 p = INSTR(tst$ + "\", "\")
160 DO WHILE p
161 h$ = MID$(tst$, op, p - op)
162 IF LEFT$(h$, 1) = "X" THEN
163 opCodeVal$ = CHR$(VAL("&H" + MID$(h$, 2)))
164 EXIT DO
165 ELSE
166 SELECT CASE h$
167 CASE "1", "2", "3"
168 NextIsOpCode = 1
169 CASE "4"
170 opCodeVal$ = CHR$(&H7) + CHR$(&H17) + CHR$(&H1F)
171 EXIT DO
172 CASE "5"
173 opCodeVal$ = CHR$(&HA1) + CHR$(&HA9)
174 EXIT DO
175 CASE "6"
176 opCodeVal$ = CHR$(&H6) + CHR$(&HE) + CHR$(&H16) + CHR$(&H1E)
177 EXIT DO
178 CASE "7"
179 opCodeVal$ = CHR$(&HA0) + CHR$(&HA8)
180 EXIT DO
181 CASE "10", "11", "12"
182 NextIsOpCode = 1
183 AddRegs = VAL(h$) - 9
184 CASE "330"
185 NextIsOpCode = 1
186 AddCCode = VAL(h$) - 329
187 CASE "17"
188 opCodeVal$ = CHR$(0)
189 EXIT DO
190 CASE ELSE
191 IF NextIsOpCode THEN
192 PRINT "Line:"; lineNr
193 PRINT "Unknown value: " + h$
195 END IF
196 END SELECT
197 END IF
198 op = p + 1
199 p = INSTR(op, tst$ + "\", "\")
200 LOOP
201 IF (p = 0) THEN
202 PRINT "No opcode found in line"; lineNr
203 PRINT "Line:"
204 PRINT l$
206 END IF
208 IF NoDebug = 0 THEN
209 FOR a = 1 TO LEN(opCodeVal$)
210 h = ASC(MID$(opCodeVal$, a, 1))
211 OpCodeStr$ = MKI$(OpCodeDebug)
212 IF AddRegs THEN
213 EndNr = 7
214 ELSEIF AddCCode THEN
215 EndNr = 15
216 ELSE
217 EndNr = 0
218 END IF
219 FOR b = 0 TO EndNr
220 OpCodeList$(h + b) = OpCodeList$(h + b) + OpCodeStr$
221 NEXT
222 NEXT
223 OpCodeDebug = OpCodeDebug + 1
224 END IF
226 skipOpCode:
227 OpCodes = OpCodes + 1
228 LineOfs$ = LineOfs$ + MKL$(NowLineOfs&)
229 LineLg = 1
230 h$ = CHR$(NoDebug)
231 PUT #3, NowLineOfs&, h$
232 NowLineOfs& = NowLineOfs& + 1
233 FOR a = 1 TO 5
234 lg = LEN(StrucData$(a))
235 h$ = CHR$(lg) + StrucData$(a)
236 PUT #3, NowLineOfs&, h$
237 NowLineOfs& = NowLineOfs& + lg + 1
238 LineLg = LineLg + lg + 1
239 NEXT
240 LineOfs$ = LineOfs$ + MKI$(LineLg)
241 END IF
242 END IF
243 WEND
244 LOCATE , 1
245 PRINT lineNr, OpCodes, OpCodeDebug
249 ' creating insnsa.c
253 PRINT "Creating INSNSA.C"
255 OPEN "O", 2, "insnsa.c"
256 strBegStart$ = "static struct itemplate instrux_"
257 strBegEnd$ = "[] = {"
258 strEnd$ = " {-1}" + crlf$ + "};" + crlf$
260 PRINT #2, "/* This file auto-generated from insns.dat by insns.bas - don't edit it */"
261 PRINT #2, ""
262 PRINT #2, "#include <stdio.h>"
263 PRINT #2, "#include " + qt$ + "nasm.h" + qt$
264 PRINT #2, "#include " + qt$ + "insns.h" + qt$
265 PRINT #2, ""
267 oldOpCode$ = ""
268 pOfs = 1
269 FOR a = 1 TO OpCodes
270 LineOfs& = CVL(MID$(LineOfs$, pOfs, 4))
271 l$ = SPACE$(CVI(MID$(LineOfs$, pOfs + 4, 2)))
272 pOfs = pOfs + 6
273 GET #3, LineOfs&, l$
275 ' split data into fields
276 NoDebug = ASC(LEFT$(l$, 1))
277 pLn = 2
278 FOR b = 1 TO 5
279 lgLn = ASC(MID$(l$, pLn, 1))
280 StrucData$(b) = MID$(l$, pLn + 1, lgLn)
281 pLn = pLn + lgLn + 1
282 NEXT
284 IF oldOpCode$ <> StrucData$(1) THEN
285 Instructs$ = Instructs$ + StrucData$(1) + CHR$(0)
286 IF LEN(oldOpCode$) THEN PRINT #2, strEnd$
287 PRINT #2, strBegStart$ + StrucData$(1) + strBegEnd$
288 oldOpCode$ = StrucData$(1)
289 END IF
290 SELECT CASE UCASE$(StrucData$(3))
291 CASE "IGNORE"
292 CASE ELSE
293 PRINT #2, " {I_" + oldOpCode$ + ", " + StrucData$(5) + ", {" + StrucData$(2) + "}, " + qt$ + StrucData$(3) + qt$ + ", " + StrucData$(4) + "},"
294 END SELECT
295 NEXT
296 IF LEN(oldOpCode$) THEN PRINT #2, strEnd$
298 PRINT #2, "struct itemplate *nasm_instructions[] = {"
299 op = 1
300 p = INSTR(Instructs$, CHR$(0))
301 WHILE p
302 h$ = MID$(Instructs$, op, p - op)
303 PRINT #2, " instrux_" + h$ + ","
304 op = p + 1
305 p = INSTR(op, Instructs$, CHR$(0))
306 WEND
307 PRINT #2, "};"
309 CLOSE 2
314 ' creating insnsd.c
318 PRINT "Creating INSNSD.C"
320 OPEN "O", 2, "insnsd.c"
322 PRINT #2, "/* This file auto-generated from insns.dat by insns.bas - don't edit it */"
323 PRINT #2, ""
324 PRINT #2, "#include <stdio.h>"
325 PRINT #2, "#include " + qt$ + "nasm.h" + qt$
326 PRINT #2, "#include " + qt$ + "insns.h" + qt$
327 PRINT #2, ""
330 PRINT #2, "static struct itemplate instrux[] = {"
331 pOfs = 1
332 FOR a = 1 TO OpCodes
333 LineOfs& = CVL(MID$(LineOfs$, pOfs, 4))
334 l$ = SPACE$(CVI(MID$(LineOfs$, pOfs + 4, 2)))
335 pOfs = pOfs + 6
336 GET #3, LineOfs&, l$
338 ' split data into fields
339 NoDebug = ASC(LEFT$(l$, 1))
340 pLn = 2
341 FOR b = 1 TO 5
342 lgLn = ASC(MID$(l$, pLn, 1))
343 StrucData$(b) = MID$(l$, pLn + 1, lgLn)
344 pLn = pLn + lgLn + 1
345 NEXT
347 IF NoDebug OR (UCASE$(StrucData$(3)) = "IGNORE") THEN
348 ' ignorieren
349 ELSE
350 PRINT #2, " {I_" + StrucData$(1) + ", " + StrucData$(5) + ", {" + StrucData$(2) + "}, " + qt$ + StrucData$(3) + qt$ + ", " + StrucData$(4) + "},"
351 END IF
352 NEXT
353 PRINT #2, " {-1}" + crlf$ + "};" + crlf$
356 OpCodeBegS$ = "static struct itemplate *itable_"
357 OpCodeBegE$ = "[] = {"
358 OpCodeEnd$ = " NULL" + crlf$ + "};" + crlf$
360 FOR a = 0 TO 255
361 PRINT #2, OpCodeBegS$ + RIGHT$("00" + HEX$(a), 2) + OpCodeBegE$
362 h$ = OpCodeList$(a)
363 FOR b = 1 TO LEN(h$) STEP 2
364 OpCodePos = CVI(MID$(h$, b, 2))
365 PRINT #2, " instrux +" + STR$(OpCodePos) + ","
366 NEXT
367 PRINT #2, OpCodeEnd$
368 NEXT
370 PRINT #2, "struct itemplate **itable[] = {"
371 FOR a = 0 TO 255
372 PRINT #2, " itable_" + RIGHT$("00" + HEX$(a), 2) + ","
373 NEXT
374 PRINT #2, "};"
376 CLOSE 2
380 CLOSE 3
381 KILL "insns.tmp"
382 CLOSE 1
383 SYSTEM
385 FUNCTION ReplaceOp$ (a$)
386 tst$ = UCASE$(a$)
387 SELECT CASE tst$
388 ' CASE "ND"
389 ' ReplaceOp$ = ""
390 CASE "VOID", ""
391 ReplaceOp$ = "0"
392 CASE "IMM"
393 ReplaceOp$ = "IMMEDIATE"
394 CASE "MEM"
395 ReplaceOp$ = "MEMORY"
396 CASE "MEM8", "MEM16", "MEM32", "MEM64", "MEM80"
397 ReplaceOp$ = "MEMORY|BITS" + MID$(tst$, 4)
398 CASE "REG8", "REG16", "REG32"
399 ReplaceOp$ = tst$
400 CASE "RM8", "RM16", "RM32"
401 ReplaceOp$ = "REGMEM|BITS" + MID$(tst$, 3)
402 CASE "IMM8", "IMM16", "IMM32"
403 ReplaceOp$ = "IMMEDIATE|BITS" + MID$(tst$, 4)
404 CASE ELSE
405 ReplaceOp$ = tst$
406 END SELECT
407 END FUNCTION
409 FUNCTION Min% (a%, b%)
410 IF a% < b% THEN Min% = a% ELSE Min% = b%
411 END FUNCTION
413 FUNCTION StrAscii (a$)
414 IF LEN(a$) = 0 THEN
415 StrAscii = -1
416 ELSE
417 StrAscii = ASC(a$)
418 END IF
419 END FUNCTION
421 ' same as =INSTR(SearchStart, SearchIn, ANY SearchFor$) in PowerBASIC(tm)
423 FUNCTION StrInstrLeft (SearchStart, SearchIn$, SearchFor$)
424 ValuesCount = LEN(SearchFor$)
425 MaxValue = LEN(SearchIn$) + 1
426 MinValue = MaxValue
427 FOR Counter1 = 1 TO ValuesCount
428 SearchChar$ = MID$(SearchFor$, Counter1, 1)
429 hVal2 = INSTR(SearchStart, SearchIn$, SearchChar$)
430 IF hVal2 > 0 THEN MinValue = Min%(hVal2, MinValue)
431 NEXT
432 IF MinValue = MaxValue THEN MinValue = 0
433 StrInstrLeft = MinValue
434 END FUNCTION
437 ' This is a very damn fuckin' shit version of this splitting routine.
438 ' At this time, it's not very useful :]
440 SUB StrSplitString (SplitString$, SplitChars$, SplitField$(), SplitCount)
441 StartIndex = LBOUND(SplitField$)
442 LastIndex = UBOUND(SplitField$)
443 ActualIndex& = StartIndex
444 SplitCount = 0
446 LastPos = 1
447 FoundPos = StrInstrLeft(LastPos, SplitString$, SplitChars$ + CHR$(34))
448 GetDirect = 0
449 EndLoop = 0
450 TempString$ = ""
451 DO WHILE FoundPos > 0
452 FoundCharVal = StrAscii(MID$(SplitString$, FoundPos, 1))
453 PosDiff = (FoundPos - LastPos) + 1
454 SELECT CASE FoundCharVal
455 CASE 34
456 TempString$ = TempString$ + MID$(SplitString$, LastPos, PosDiff - 1)
457 SELECT CASE EndLoop
458 CASE 0
459 EndLoop = 2
460 CASE 3
461 EndLoop = 0
462 END SELECT
463 CASE ELSE
464 TempString$ = TempString$ + MID$(SplitString$, LastPos, PosDiff - 1)
465 SplitField$(ActualIndex&) = TempString$
466 TempString$ = ""
467 ActualIndex& = ActualIndex& + 1
468 IF ActualIndex& > LastIndex THEN
469 ActualIndex& = LastIndex
470 EndLoop = 1
471 END IF
472 END SELECT
473 SELECT CASE EndLoop
474 CASE 0
476 LastPos = FoundPos + 1
477 FoundPos = StrInstrLeft(LastPos, SplitString$, SplitChars$)
478 LOOP WHILE LastPos = FoundPos
479 FoundPos = StrInstrLeft(LastPos, SplitString$, SplitChars$ + CHR$(34))
480 CASE 1
481 FoundPos = 0
482 LastPos = LEN(SplitString$) + 1
483 CASE 2
484 EndLoop = 3
485 LastPos = FoundPos + 1
486 FoundPos = StrInstrLeft(LastPos, SplitString$, CHR$(34))
487 IF FoundPos = 0 THEN
488 SplitString$ = SplitString$ + CHR$(34)
489 FoundPos = LEN(SplitString$)
490 END IF
491 END SELECT
492 LOOP
493 IF EndLoop = 0 THEN
494 IF LEN(TempString$) > 0 THEN
495 SplitField$(ActualIndex&) = TempString$
496 ELSEIF LastPos <= LEN(SplitString$) THEN
497 SplitField$(ActualIndex&) = MID$(SplitString$, LastPos)
498 ELSE
499 ActualIndex& = ActualIndex& - 1
500 END IF
501 END IF
502 FOR a = ActualIndex& + 1 TO LastIndex
503 SplitField$(a) = ""
504 NEXT
505 SplitCount = (ActualIndex& - StartIndex) + 1
506 END SUB
508 FUNCTION StrTrim$ (a$, b$)
509 StrTrim$ = StrTrimRight$(StrTrimLeft$(a$, b$), b$)
510 END FUNCTION
512 FUNCTION StrTrimLeft$ (a$, b$) 'public
513 p = 0
514 l = LEN(a$)
516 p = p + 1
517 t$ = MID$(a$, p, 1)
518 LOOP WHILE (p < l) AND (INSTR(b$, t$) > 0)
519 StrTrimLeft$ = MID$(a$, p)
520 END FUNCTION
522 FUNCTION StrTrimRight$ (a$, b$) 'public
523 l = LEN(a$)
524 p = l + 1
526 p = p - 1
527 IF p > 0 THEN
528 t$ = MID$(a$, p, 1)
529 ELSE
530 t$ = ""
531 END IF
532 LOOP WHILE (p > 0) AND (INSTR(b$, t$) > 0)
533 StrTrimRight$ = LEFT$(a$, p)
534 END FUNCTION
536 \x1a