NASM 0.98p3-hpa
[nasm/avx512.git] / insns.bas
blob5178aa63607151e5926a29af81a88bb12f701443
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 Perl-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 ' THIS PROGRAM NEEDS TO BE UPDATED -- it doesn't create insnsi.h
15 ' and insnsn.c. However, Perl interpreters are now available for both
16 ' DOS and Windows, so it seems pointless to spend the effort.
19 DEFINT A-Z
21 DECLARE FUNCTION ReplaceOp$ (a$)
22 DECLARE FUNCTION StrTrimLeft$ (a$, b$)
23 DECLARE FUNCTION StrTrimRight$ (a$, b$)
24 DECLARE FUNCTION StrTrim$ (a$, b$)
25 DECLARE SUB StrSplitString (SplitString$, SplitChars$, SplitField$(), SplitCount%)
26 DECLARE FUNCTION Min% (a%, b%)
27 DECLARE FUNCTION StrInstrLeft% (SearchStart%, SearchIn$, SearchFor$)
28 DECLARE FUNCTION StrAscii% (a$)
31 CONST MaxOpCodeBase = 3
32 CONST MaxOpCodeType = 8
34 CLS
35 DIM LineData$(1 TO 2)
36 DIM StrucData$(1 TO 5)
37 DIM OpCodeList$(0 TO 255)
38 DIM OpCodeByte(1 TO MaxOpCodeType, 1 TO MaxOpCodeBase)
39 DIM OpCodeStat(1 TO 10) ' don't need mode :)
41 Instructs$ = ""
42 LineOfs$ = ""
44 OPEN "I", 1, "insns.dat"
45 OPEN "B", 3, "insns.tmp"
47 qt$ = CHR$(34)
48 crlf$ = CHR$(13) + CHR$(10)
52 ' preprocessing the current file
55 HexChar$ = "0123456789ABCDEF"
57 PRINT "Preprocessing INSNS.DAT"
58 OpCodes = 0
59 OpCodeDebug = 0
60 NowLineOfs& = 1
61 lineNr = 0
62 WHILE NOT EOF(1)
63 lineNr = lineNr + 1
64 IF (lineNr AND 15) = 0 THEN
65 LOCATE , 1
66 PRINT lineNr, OpCodes, OpCodeDebug;
67 END IF
69 LINE INPUT #1, l$
70 CALL StrSplitString(l$, ";", LineData$(), SplitCount)
71 IF SplitCount THEN
72 LineData$(1) = StrTrim$(LineData$(1), CHR$(9) + " ")
73 IF LEN(LineData$(1)) THEN
74 CALL StrSplitString(LineData$(1), " ", StrucData$(), cntSplit)
75 IF cntSplit <> 4 THEN
76 PRINT "line"; lineNr; " does not contain four fields"
77 END
78 END IF
80 tst$ = UCASE$(StrucData$(2))
81 res$ = ""
82 cnt% = 1
83 isfirst = 1
84 op = 1
85 p = StrInstrLeft(1, tst$ + ",", "|:,")
86 WHILE p
87 h$ = ReplaceOp$(MID$(tst$, op, p - op))
88 IF LEN(h$) THEN
89 SELECT CASE MID$(tst$, p, 1)
90 CASE ""
91 IF isfirst THEN
92 res$ = res$ + h$
93 ELSE
94 res$ = res$ + "|" + h$
95 END IF
96 isfirst = 0
97 CASE ","
98 IF isfirst THEN
99 res$ = res$ + h$ + ","
100 ELSE
101 res$ = res$ + "|" + h$ + ","
102 END IF
103 cnt% = cnt% + 1
104 isfirst = 1
105 CASE "|"
106 IF isfirst THEN
107 res$ = res$ + h$
108 ELSE
109 res$ = res$ + "|" + h$
110 END IF
111 isfirst = 0
112 CASE ":"
113 res$ = res$ + h$ + "|COLON,"
114 cnt% = cnt% + 1
115 END SELECT
116 END IF
117 op = p + 1
118 p = StrInstrLeft(op, tst$ + ",", "|:,")
119 WEND
120 FOR a = cnt% + 1 TO 3
121 res$ = res$ + ",0"
122 NEXT
123 StrucData$(2) = res$
124 IF LEFT$(res$, 2) = "0," THEN cnt% = cnt% - 1
125 StrucData$(5) = LTRIM$(STR$(cnt%))
127 NoDebug = 0
128 res$ = ""
129 tst$ = UCASE$(StrucData$(4))
130 op = 1
131 p = INSTR(tst$ + ",", ",")
132 isfirst = 1
133 WHILE p
134 h$ = MID$(tst$, op, p - op)
135 IF h$ = "ND" THEN
136 NoDebug = 1
137 ELSE
138 IF isfirst THEN
139 res$ = res$ + "IF_" + h$
140 ELSE
141 res$ = res$ + "|IF_" + h$
142 END IF
143 isfirst = 0
144 END IF
145 op = p + 1
146 p = INSTR(op, tst$ + ",", ",")
147 WEND
148 StrucData$(4) = res$
150 tst$ = UCASE$(StrucData$(3))
151 SELECT CASE tst$
152 CASE "IGNORE"
153 GOTO skipOpCode
154 CASE "\0", "\340"
155 OpCodeDebug = OpCodeDebug + 1 ' don't forget to increment
156 GOTO skipOpCode
157 END SELECT
159 AddRegs = 0
160 AddCCode = 0
161 NextIsOpCode = 0
162 opCodeVal$ = ""
163 op = 1
164 p = INSTR(tst$ + "\", "\")
165 DO WHILE p
166 h$ = MID$(tst$, op, p - op)
167 IF LEFT$(h$, 1) = "X" THEN
168 opCodeVal$ = CHR$(VAL("&H" + MID$(h$, 2)))
169 EXIT DO
170 ELSE
171 SELECT CASE h$
172 CASE "1", "2", "3"
173 NextIsOpCode = 1
174 CASE "4"
175 opCodeVal$ = CHR$(&H7) + CHR$(&H17) + CHR$(&H1F)
176 EXIT DO
177 CASE "5"
178 opCodeVal$ = CHR$(&HA1) + CHR$(&HA9)
179 EXIT DO
180 CASE "6"
181 opCodeVal$ = CHR$(&H6) + CHR$(&HE) + CHR$(&H16) + CHR$(&H1E)
182 EXIT DO
183 CASE "7"
184 opCodeVal$ = CHR$(&HA0) + CHR$(&HA8)
185 EXIT DO
186 CASE "10", "11", "12"
187 NextIsOpCode = 1
188 AddRegs = VAL(h$) - 9
189 CASE "330"
190 NextIsOpCode = 1
191 AddCCode = VAL(h$) - 329
192 CASE "17"
193 opCodeVal$ = CHR$(0)
194 EXIT DO
195 CASE ELSE
196 IF NextIsOpCode THEN
197 PRINT "Line:"; lineNr
198 PRINT "Unknown value: " + h$
200 END IF
201 END SELECT
202 END IF
203 op = p + 1
204 p = INSTR(op, tst$ + "\", "\")
205 LOOP
206 IF (p = 0) THEN
207 PRINT "No opcode found in line"; lineNr
208 PRINT "Line:"
209 PRINT l$
211 END IF
213 IF NoDebug = 0 THEN
214 FOR a = 1 TO LEN(opCodeVal$)
215 h = ASC(MID$(opCodeVal$, a, 1))
216 OpCodeStr$ = MKI$(OpCodeDebug)
217 IF AddRegs THEN
218 EndNr = 7
219 ELSEIF AddCCode THEN
220 EndNr = 15
221 ELSE
222 EndNr = 0
223 END IF
224 FOR b = 0 TO EndNr
225 OpCodeList$(h + b) = OpCodeList$(h + b) + OpCodeStr$
226 NEXT
227 NEXT
228 OpCodeDebug = OpCodeDebug + 1
229 END IF
231 skipOpCode:
232 OpCodes = OpCodes + 1
233 LineOfs$ = LineOfs$ + MKL$(NowLineOfs&)
234 LineLg = 1
235 h$ = CHR$(NoDebug)
236 PUT #3, NowLineOfs&, h$
237 NowLineOfs& = NowLineOfs& + 1
238 FOR a = 1 TO 5
239 lg = LEN(StrucData$(a))
240 h$ = CHR$(lg) + StrucData$(a)
241 PUT #3, NowLineOfs&, h$
242 NowLineOfs& = NowLineOfs& + lg + 1
243 LineLg = LineLg + lg + 1
244 NEXT
245 LineOfs$ = LineOfs$ + MKI$(LineLg)
246 END IF
247 END IF
248 WEND
249 LOCATE , 1
250 PRINT lineNr, OpCodes, OpCodeDebug
254 ' creating insnsa.c
258 PRINT "Creating INSNSA.C"
260 OPEN "O", 2, "insnsa.c"
261 strBegStart$ = "static struct itemplate instrux_"
262 strBegEnd$ = "[] = {"
263 strEnd$ = " {-1}" + crlf$ + "};" + crlf$
265 PRINT #2, "/* This file auto-generated from insns.dat by insns.bas - don't edit it */"
266 PRINT #2, ""
267 PRINT #2, "#include <stdio.h>"
268 PRINT #2, "#include " + qt$ + "nasm.h" + qt$
269 PRINT #2, "#include " + qt$ + "insns.h" + qt$
270 PRINT #2, ""
272 oldOpCode$ = ""
273 pOfs = 1
274 FOR a = 1 TO OpCodes
275 LineOfs& = CVL(MID$(LineOfs$, pOfs, 4))
276 l$ = SPACE$(CVI(MID$(LineOfs$, pOfs + 4, 2)))
277 pOfs = pOfs + 6
278 GET #3, LineOfs&, l$
280 ' split data into fields
281 NoDebug = ASC(LEFT$(l$, 1))
282 pLn = 2
283 FOR b = 1 TO 5
284 lgLn = ASC(MID$(l$, pLn, 1))
285 StrucData$(b) = MID$(l$, pLn + 1, lgLn)
286 pLn = pLn + lgLn + 1
287 NEXT
289 IF oldOpCode$ <> StrucData$(1) THEN
290 Instructs$ = Instructs$ + StrucData$(1) + CHR$(0)
291 IF LEN(oldOpCode$) THEN PRINT #2, strEnd$
292 PRINT #2, strBegStart$ + StrucData$(1) + strBegEnd$
293 oldOpCode$ = StrucData$(1)
294 END IF
295 SELECT CASE UCASE$(StrucData$(3))
296 CASE "IGNORE"
297 CASE ELSE
298 PRINT #2, " {I_" + oldOpCode$ + ", " + StrucData$(5) + ", {" + StrucData$(2) + "}, " + qt$ + StrucData$(3) + qt$ + ", " + StrucData$(4) + "},"
299 END SELECT
300 NEXT
301 IF LEN(oldOpCode$) THEN PRINT #2, strEnd$
303 PRINT #2, "struct itemplate *nasm_instructions[] = {"
304 op = 1
305 p = INSTR(Instructs$, CHR$(0))
306 WHILE p
307 h$ = MID$(Instructs$, op, p - op)
308 PRINT #2, " instrux_" + h$ + ","
309 op = p + 1
310 p = INSTR(op, Instructs$, CHR$(0))
311 WEND
312 PRINT #2, "};"
314 CLOSE 2
319 ' creating insnsd.c
323 PRINT "Creating INSNSD.C"
325 OPEN "O", 2, "insnsd.c"
327 PRINT #2, "/* This file auto-generated from insns.dat by insns.bas - don't edit it */"
328 PRINT #2, ""
329 PRINT #2, "#include <stdio.h>"
330 PRINT #2, "#include " + qt$ + "nasm.h" + qt$
331 PRINT #2, "#include " + qt$ + "insns.h" + qt$
332 PRINT #2, ""
335 PRINT #2, "static struct itemplate instrux[] = {"
336 pOfs = 1
337 FOR a = 1 TO OpCodes
338 LineOfs& = CVL(MID$(LineOfs$, pOfs, 4))
339 l$ = SPACE$(CVI(MID$(LineOfs$, pOfs + 4, 2)))
340 pOfs = pOfs + 6
341 GET #3, LineOfs&, l$
343 ' split data into fields
344 NoDebug = ASC(LEFT$(l$, 1))
345 pLn = 2
346 FOR b = 1 TO 5
347 lgLn = ASC(MID$(l$, pLn, 1))
348 StrucData$(b) = MID$(l$, pLn + 1, lgLn)
349 pLn = pLn + lgLn + 1
350 NEXT
352 IF NoDebug OR (UCASE$(StrucData$(3)) = "IGNORE") THEN
353 ' ignorieren
354 ELSE
355 PRINT #2, " {I_" + StrucData$(1) + ", " + StrucData$(5) + ", {" + StrucData$(2) + "}, " + qt$ + StrucData$(3) + qt$ + ", " + StrucData$(4) + "},"
356 END IF
357 NEXT
358 PRINT #2, " {-1}" + crlf$ + "};" + crlf$
361 OpCodeBegS$ = "static struct itemplate *itable_"
362 OpCodeBegE$ = "[] = {"
363 OpCodeEnd$ = " NULL" + crlf$ + "};" + crlf$
365 FOR a = 0 TO 255
366 PRINT #2, OpCodeBegS$ + RIGHT$("00" + HEX$(a), 2) + OpCodeBegE$
367 h$ = OpCodeList$(a)
368 FOR b = 1 TO LEN(h$) STEP 2
369 OpCodePos = CVI(MID$(h$, b, 2))
370 PRINT #2, " instrux +" + STR$(OpCodePos) + ","
371 NEXT
372 PRINT #2, OpCodeEnd$
373 NEXT
375 PRINT #2, "struct itemplate **itable[] = {"
376 FOR a = 0 TO 255
377 PRINT #2, " itable_" + RIGHT$("00" + HEX$(a), 2) + ","
378 NEXT
379 PRINT #2, "};"
381 CLOSE 2
385 CLOSE 3
386 KILL "insns.tmp"
387 CLOSE 1
388 SYSTEM
390 FUNCTION ReplaceOp$ (a$)
391 tst$ = UCASE$(a$)
392 SELECT CASE tst$
393 ' CASE "ND"
394 ' ReplaceOp$ = ""
395 CASE "VOID", ""
396 ReplaceOp$ = "0"
397 CASE "IMM"
398 ReplaceOp$ = "IMMEDIATE"
399 CASE "MEM"
400 ReplaceOp$ = "MEMORY"
401 CASE "MEM8", "MEM16", "MEM32", "MEM64", "MEM80"
402 ReplaceOp$ = "MEMORY|BITS" + MID$(tst$, 4)
403 CASE "REG8", "REG16", "REG32"
404 ReplaceOp$ = tst$
405 CASE "RM8", "RM16", "RM32"
406 ReplaceOp$ = "REGMEM|BITS" + MID$(tst$, 3)
407 CASE "IMM8", "IMM16", "IMM32"
408 ReplaceOp$ = "IMMEDIATE|BITS" + MID$(tst$, 4)
409 CASE ELSE
410 ReplaceOp$ = tst$
411 END SELECT
412 END FUNCTION
414 FUNCTION Min% (a%, b%)
415 IF a% < b% THEN Min% = a% ELSE Min% = b%
416 END FUNCTION
418 FUNCTION StrAscii (a$)
419 IF LEN(a$) = 0 THEN
420 StrAscii = -1
421 ELSE
422 StrAscii = ASC(a$)
423 END IF
424 END FUNCTION
426 ' same as =INSTR(SearchStart, SearchIn, ANY SearchFor$) in PowerBASIC(tm)
428 FUNCTION StrInstrLeft (SearchStart, SearchIn$, SearchFor$)
429 ValuesCount = LEN(SearchFor$)
430 MaxValue = LEN(SearchIn$) + 1
431 MinValue = MaxValue
432 FOR Counter1 = 1 TO ValuesCount
433 SearchChar$ = MID$(SearchFor$, Counter1, 1)
434 hVal2 = INSTR(SearchStart, SearchIn$, SearchChar$)
435 IF hVal2 > 0 THEN MinValue = Min%(hVal2, MinValue)
436 NEXT
437 IF MinValue = MaxValue THEN MinValue = 0
438 StrInstrLeft = MinValue
439 END FUNCTION
442 ' This is a very damn fuckin' shit version of this splitting routine.
443 ' At this time, it's not very useful :]
445 SUB StrSplitString (SplitString$, SplitChars$, SplitField$(), SplitCount)
446 StartIndex = LBOUND(SplitField$)
447 LastIndex = UBOUND(SplitField$)
448 ActualIndex& = StartIndex
449 SplitCount = 0
451 LastPos = 1
452 FoundPos = StrInstrLeft(LastPos, SplitString$, SplitChars$ + CHR$(34))
453 GetDirect = 0
454 EndLoop = 0
455 TempString$ = ""
456 DO WHILE FoundPos > 0
457 FoundCharVal = StrAscii(MID$(SplitString$, FoundPos, 1))
458 PosDiff = (FoundPos - LastPos) + 1
459 SELECT CASE FoundCharVal
460 CASE 34
461 TempString$ = TempString$ + MID$(SplitString$, LastPos, PosDiff - 1)
462 SELECT CASE EndLoop
463 CASE 0
464 EndLoop = 2
465 CASE 3
466 EndLoop = 0
467 END SELECT
468 CASE ELSE
469 TempString$ = TempString$ + MID$(SplitString$, LastPos, PosDiff - 1)
470 SplitField$(ActualIndex&) = TempString$
471 TempString$ = ""
472 ActualIndex& = ActualIndex& + 1
473 IF ActualIndex& > LastIndex THEN
474 ActualIndex& = LastIndex
475 EndLoop = 1
476 END IF
477 END SELECT
478 SELECT CASE EndLoop
479 CASE 0
481 LastPos = FoundPos + 1
482 FoundPos = StrInstrLeft(LastPos, SplitString$, SplitChars$)
483 LOOP WHILE LastPos = FoundPos
484 FoundPos = StrInstrLeft(LastPos, SplitString$, SplitChars$ + CHR$(34))
485 CASE 1
486 FoundPos = 0
487 LastPos = LEN(SplitString$) + 1
488 CASE 2
489 EndLoop = 3
490 LastPos = FoundPos + 1
491 FoundPos = StrInstrLeft(LastPos, SplitString$, CHR$(34))
492 IF FoundPos = 0 THEN
493 SplitString$ = SplitString$ + CHR$(34)
494 FoundPos = LEN(SplitString$)
495 END IF
496 END SELECT
497 LOOP
498 IF EndLoop = 0 THEN
499 IF LEN(TempString$) > 0 THEN
500 SplitField$(ActualIndex&) = TempString$
501 ELSEIF LastPos <= LEN(SplitString$) THEN
502 SplitField$(ActualIndex&) = MID$(SplitString$, LastPos)
503 ELSE
504 ActualIndex& = ActualIndex& - 1
505 END IF
506 END IF
507 FOR a = ActualIndex& + 1 TO LastIndex
508 SplitField$(a) = ""
509 NEXT
510 SplitCount = (ActualIndex& - StartIndex) + 1
511 END SUB
513 FUNCTION StrTrim$ (a$, b$)
514 StrTrim$ = StrTrimRight$(StrTrimLeft$(a$, b$), b$)
515 END FUNCTION
517 FUNCTION StrTrimLeft$ (a$, b$) 'public
518 p = 0
519 l = LEN(a$)
521 p = p + 1
522 t$ = MID$(a$, p, 1)
523 LOOP WHILE (p < l) AND (INSTR(b$, t$) > 0)
524 StrTrimLeft$ = MID$(a$, p)
525 END FUNCTION
527 FUNCTION StrTrimRight$ (a$, b$) 'public
528 l = LEN(a$)
529 p = l + 1
531 p = p - 1
532 IF p > 0 THEN
533 t$ = MID$(a$, p, 1)
534 ELSE
535 t$ = ""
536 END IF
537 LOOP WHILE (p > 0) AND (INSTR(b$, t$) > 0)
538 StrTrimRight$ = LEFT$(a$, p)
539 END FUNCTION
541 \x1a