expected.tsv 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. # Expected results for tests/fixtures/*.pas - one line per fixture:
  2. #
  3. # <fixture-basename> OK <code> <data>
  4. # <fixture-basename> ERR <tp3-error-no> <relative-pos>
  5. #
  6. # Both the verdict AND the numbers are asserted by run_compile_tests.sh, so a
  7. # regression in the *reported error position* fails the suite just like a
  8. # regression in the generated code. That matters: error positions were once
  9. # silently wrong (a multi-character string literal swallowed the rest of the
  10. # source, so every later error pointed at end-of-file), and nothing caught it
  11. # because the old harness only printed the position for a human to squint at.
  12. #
  13. # Re-baseline deliberately, never to make a red test go green: if a fixture's
  14. # expectation has to change because the compiler legitimately improved, change
  15. # it in the same commit as the fix and say why in the message.
  16. #
  17. # ERR 102 = ENoLib, the original's "not implemented" path. The remaining ERR
  18. # rows are unimplemented features, not parser bugs:
  19. # t14 'array [..] of <type>' at its point of use
  20. # t25 a string literal used where a 16-bit word is wanted
  21. # uierror deliberate syntax error, pinned by the editor UI test
  22. #
  23. # The nine control-flow fixtures (t08 t09 t10 t11 t12 t13 t15 t27 t28) were
  24. # re-baselined upward when they were rewritten to PRINT their result, so each
  25. # has a .out file and is executed under qemu (run_com_exec.py) as well as
  26. # compiled here. Before that they assigned to a variable and fell off the end:
  27. # they asserted that the compiler produced bytes, and nothing about behaviour.
  28. # t13 also gained a second procedure, which is why it is bigger than the sum of
  29. # its parts. t08's data went 6 -> 7 because a CHAR variable joined the INTEGER.
  30. #
  31. # t02 t03 t05 t17 used to be ERR 102 as well: a multi-character literal was
  32. # rejected because writeln had no string support. They compile now, via the
  33. # inline-string path (CALL wrtinl, then <length><chars> in the code stream -
  34. # TPSRC8 pwrinlin / TPSRC4 xwrtinl), so their rows changed from ERR to OK and
  35. # their code sizes went up by the literal's own bytes.
  36. #
  37. # RE-BASELINED for v-TP3-8086-LOWERING, when conditional branches and SETcc
  38. # stopped being 386-only. Nine rows moved, every one of them UPWARD, and every
  39. # one of them by exactly the number of conditional sites in that fixture:
  40. #
  41. # +1 per site. A branch was 4 bytes (0F 8x rel16) and is now 5 (7x 03,
  42. # then the 3-byte EJMP). A comparison VALUE was 5 bytes (0F 9x rel8, then
  43. # MOV AH,0) and is now 6 (B8 01 00, 7x 01, DEC AX). So the deltas are
  44. # t09 +6 = 3 values + 3 branches, t10 +4 = 2+2, t11 +2 = 0+2,
  45. # t12 +4 = 2+2, t15 +2 = 1+1, t22 +2 = 0+2, t30 +1 = 0+1, t32 +3 = 1+2,
  46. # t33 +13 = 13 values.
  47. #
  48. # That arithmetic was CHECKED, not assumed: the site counts were counted out of
  49. # the linked images (the same CMP AX,CX and CMP AX,0000 anchors and the same
  50. # 7x 03 E9 shape that check_8086.py uses) and each row was only written after
  51. # its delta matched its count. Data sizes did not move at all. The bytes
  52. # themselves are pinned by check_8086.py, and the BEHAVIOUR is pinned by
  53. # run_com_exec.py -- this row only says how big the code is.
  54. #
  55. # RE-BASELINED when the runtime was wired into the code buffer. Every OK row
  56. # changed by exactly +3 code and -256 data, and both numbers are correct:
  57. #
  58. # +3 code the prologue now emits MOV AX,<header offset> before
  59. # CALL TU_InitMem, because InitMem takes the header offset in a
  60. # register (B8 lo hi) rather than on the stack. Previously the
  61. # prologue called offset 8, which is the hdrMax word - it only
  62. # "worked" because the runtime was not in the image at all.
  63. #
  64. # -256 data DataBytes() used to return dc, the ABSOLUTE end of the data
  65. # area, not a size. dc started at 100H, so every program reported
  66. # 256 more than it allocated - 260 for a program whose only data is
  67. # the two @@T1/@@T2 scratch words. The field is documented as
  68. # "emitted data size in bytes", so 4 is the true size and 260 was
  69. # the bug. It is a real correction, not a fit-to-the-test change:
  70. # the 6-byte rows are the fixtures that declare one global.
  71. #
  72. # ADDED for the BP displacement fix. These two fixtures are the first with
  73. # any frame access at all -- every earlier fixture put its variables in the
  74. # DATA segment, addressed absolutely, so the whole [BP+off] path had zero
  75. # coverage and a truncation there was invisible.
  76. #
  77. # t27_localvar five LOCAL variables, assigned and read back. Locals are
  78. # allocated downward from 0FFFEh and each access now costs 4
  79. # bytes (mod=10 + disp16) where it cost 3 (disp8), so its code
  80. # size reflects the fix rather than predating it. Both
  81. # encodings address the same place; only the rule for choosing
  82. # between them changed.
  83. # t28_farparam 70 declared parameters; the call passes 16, which is the
  84. # argument cap at the call site. Under TP3's frame rule the
  85. # LAST declared parameter is the one at BP+4, so p8 lands at
  86. # BP+128 and p1 at BP+142 - the first offsets a disp8 cannot
  87. # represent, since 80h is -128 and not +128. Under the old
  88. # code these two reads came from the wrong side of BP. This
  89. # fixture tests the ENCODING; it is executed too, but its .out
  90. # carries only the deterministic sum of the two slots the
  91. # sixteen pushed arguments land in (p55 + p70), never the
  92. # stack garbage that p1..p54 read. Do not read it as a claim
  93. # that a 70-argument call works.
  94. #
  95. # RE-BASELINED for the case-label fix, and this is the one re-baseline in this
  96. # file that is a CORRECTION rather than a new feature. EmMovAxSp used to emit
  97. #
  98. # 8B 44 24 00 MOV AX,[SP] <- 386 encoding, SIB byte
  99. #
  100. # which is 4 bytes. [SP] is not encodable on the 8086 at all: mod=00/rm=100
  101. # is [SI], and the SIB byte that 8B 44 needs did not exist until the 386. The
  102. # bytes were well formed, so every byte-level check passed, and fcml and qemu
  103. # both DECODED it - as MOV AX,[SI+0x24h], because that is what it is. Every
  104. # CASE label test therefore loaded a garbage address, every comparison failed,
  105. # and a case statement fell straight past its body. It now emits
  106. #
  107. # 58 50 POP AX ; PUSH AX <- 2 bytes
  108. #
  109. # which is observationally a peek. t22 has two labels, so its code is exactly
  110. # 4 bytes smaller: 96 -> 92. The number moving is the point - the old size was
  111. # the size of a wrong encoding, and a case fixture that is not executed cannot
  112. # tell you that from its size alone. t22 is executed (tests/run_com_exec.py).
  113. #
  114. # ADDED t29_readln: the first fixture that reads. It needs the CHAR class to
  115. # exist at all - see the note on TChar in Compiler.mod - so 7 data bytes where
  116. # t19 has 4 (n is 2, c is 1, and the two are 2-byte aligned, so 4 + 2 + 1
  117. # rounds up to 7) and 82 code bytes for the four runtime calls plus a literal
  118. # char argument. Its .out is compared byte for byte against qemu.
  119. #
  120. # RE-BASELINED for the procedure-skip jump. t13, t27 and t28 gained exactly
  121. # +3 code bytes: `E9 rel16`. These are the only three fixtures that declare a
  122. # PROCEDURE, and they are the only three rows that moved.
  123. #
  124. # The reason is a bug that only execution could find. The declaration part is
  125. # compiled BEFORE the main statement part, so a procedure's code lands between
  126. # the program prologue and the main body - and nothing jumped over it. A
  127. # program with a procedure ran off the end of the prologue straight into the
  128. # first procedure, which read its argument out of an uninitialised frame and
  129. # returned to address 0000h. t13_proc compiled, produced a plausible 53 bytes,
  130. # and was never run, so the suite was green over a program that could not
  131. # execute at all.
  132. #
  133. # The jump is emitted ONLY when a procedure or function is declared, which is
  134. # why the other 27 OK rows did not move. That condition is a lookahead over
  135. # the source buffer, because the jump must be emitted before the declaration
  136. # part but whether one is needed is only known after - see DeclaresProc in
  137. # Compiler.mod for why the alternative (always emit it) was rejected.
  138. #
  139. # t13_proc 53 -> 56
  140. # t27_localvar 122 -> 125
  141. # t28_farparam 123 -> 126
  142. # t31_procparam 66 -> 69
  143. #
  144. # t31_procparam is the fixture that proves the fix by running: it declares a
  145. # procedure, calls it, and prints what the procedure wrote. Before the fix it
  146. # never halted at all.
  147. #
  148. # ADDED t30/t31/t32, all three now EXECUTED (not just compiled):
  149. #
  150. # t30_forloop `for i := 1 to 5 do s := s + i` printed 21, not 15. The loop
  151. # test was emitted AFTER the body, making it a post-test loop:
  152. # the body ran a sixth time with i = 6. The code size and the
  153. # instruction bytes were both already correct - only the ORDER
  154. # was wrong, and no byte-level check can observe an order. The
  155. # test now precedes the body, so 96 bytes both before and after
  156. # this fix, which is the whole point: the number never moved and
  157. # the behaviour did.
  158. # t31_procparam procedure + one parameter. The non-termination above.
  159. # t32_forexit `for` with `exit` in the body. Two faults, both invisible to
  160. # a size check: the loop's exits were patched to the position
  161. # just past the body, which in a FOR is the STEP, so `exit`
  162. # incremented the control variable and jumped back into the test
  163. # - it did not exit; and the EXIT handler also emitted ADD SP,2
  164. # while the loop's `done` label emitted it again, dropping four
  165. # bytes off a stack that had two to give. Exits are now patched
  166. # at `done`, and the handler no longer touches the stack.
  167. # t33_cmpops all six relational operators as VALUES, each with a true case,
  168. # a false case and the equality boundary, plus one signed pair.
  169. # Added while making the 8086 branch/compare lowering checkable:
  170. # measuring which conditions the suite actually emitted showed
  171. # that `=', `<>' and `<=' were never used in a comparison at all,
  172. # because `writeln (a = b)` had no fixture. Only `<', `>' and
  173. # `>=' had coverage - and `>' vs `>=' had ALREADY been swapped
  174. # once (bug 29), so a hole either side of the operators that
  175. # were covered is the last place to leave one. m := -1, n := -2
  176. # makes the last line signed: unsigned, -1 > -2 is FALSE, so that
  177. # one line is what tells SETG from a byte compare.
  178. #
  179. # t36_argclobber eight lines of hand-derived output, added BEFORE the fix it
  180. # covers: this row was written while the compiler still lost a
  181. # computed argument, was proved red by running it, and its
  182. # numbers did not move when the fix landed - the fix reorders
  183. # bytes rather than adding them, so the same size came out of a
  184. # different order. A number that never moved and a behaviour
  185. # that did is the same shape as t30 above.
  186. t01_minimal OK 29 4
  187. t02_writeln OK 38 4
  188. t03_inline_comment OK 38 4
  189. t04_var OK 48 6
  190. t05_own_line_comment OK 38 4
  191. t06_two_args OK 52 4
  192. t07_big OK 102 6
  193. t08_const OK 76 7
  194. t09_if OK 195 6
  195. t10_while OK 151 6
  196. t11_for OK 144 6
  197. t12_repeat OK 137 6
  198. t13_proc OK 126 6
  199. t14_types ERR 102 83
  200. t15_label OK 90 6
  201. t16_str1 OK 42 4
  202. t17_two_str OK 45 4
  203. t18_writeln_bare OK 32 4
  204. t19_int1 OK 42 4
  205. t20_str3 OK 62 4
  206. t21_mixed OK 62 4
  207. t22_case OK 94 6
  208. t23_str_empty OK 36 4
  209. t24_str_quote OK 41 4
  210. t25_str_as_value ERR 102 48
  211. t26_str_mixed_args OK 58 4
  212. t27_localvar OK 256 6
  213. t28_farparam OK 153 8
  214. t29_readln OK 82 7
  215. t30_forloop OK 97 8
  216. t31_procparam OK 69 6
  217. t32_forexit OK 138 8
  218. t33_cmpops OK 404 12
  219. t34_arith OK 448 8
  220. t35_not OK 224 7
  221. t36_argclobber OK 492 12
  222. uierror ERR 41 331