ceg.tr 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587
  1. .nr PS 12
  2. .nr VS 14
  3. .nr LL 6i
  4. .tr ~
  5. .TL
  6. The Code Expander Generator
  7. .AU
  8. Frans Kaashoek
  9. Koen Langendoen
  10. .AI
  11. Dept. of Mathematics and Computer Science
  12. Vrije Universiteit
  13. Amsterdam, The Netherlands
  14. .NH
  15. Introduction
  16. .PP
  17. A \fBcode expander\fR (\fBce\fR for short) is a part of the
  18. Amsterdam Compiler Kit
  19. .[
  20. toolkit
  21. .]
  22. (\fBACK\fR) and provides the user with
  23. high-speed generation of medium-quality code. Although conceptually
  24. equivalent to the more usual \fBcode generator\fR, it differs in some
  25. aspects.
  26. .PP
  27. Normally, a program to be compiled with \fBACK\fR
  28. is first fed to the preprocessor. The output of the preprocessor goes
  29. into the appropriate front end, which produces EM
  30. .[
  31. block
  32. .]
  33. (a
  34. machine independent low level intermediate code). The generated EM code is fed
  35. into the peephole optimizer, which scans it with a window of a few instructions,
  36. replacing certain inefficient code sequences by better ones. After the
  37. peephole optimizer a back end follows, which produces high-quality assembly code.
  38. The assembly code goes via the target optimizer into the assembler and the
  39. object code then goes into the
  40. linker/loader, the final component in the pipeline.
  41. .PP
  42. For various applications
  43. this scheme is too slow. When debugging, for example,
  44. compile time is more important than execution time of a program.
  45. For this purpose a new scheme is introduced:
  46. .IP \ \ 1:
  47. The code generator and assembler are
  48. replaced by a library, the \fBcode expander\fR, consisting of a set of
  49. routines, one for every EM-instruction. Each routine expands its EM-instruction
  50. into relocatable object code. In contrast, the usual ACK code generator uses
  51. expensive pattern matching on sequences of EM-instructions.
  52. The peephole and target optimizer are not used.
  53. .IP \ \ 2:
  54. These routines replace the usual EM-generating routines in the front end; this
  55. eliminates the overhead of intermediate files.
  56. .LP
  57. This results in a fast compiler producing object file, ready to be
  58. linked and loaded, at the cost of unoptimized object code.
  59. .PP
  60. Because of the
  61. simple nature of the code expander, it is much easier to build, to debug, and to
  62. test. Experience has demonstrated that a code expander can be constructed,
  63. debugged, and tested in less than two weeks.
  64. .PP
  65. This document describes the tools for automatically generating a
  66. \fBce\fR (a library of C files) from two tables and
  67. a few machine-dependent functions.
  68. A thorough knowledge of EM is necessary to understand this document.
  69. .NH
  70. The code expander generator
  71. .PP
  72. The code expander generator (\fBceg\fR) generates a code expander from
  73. two tables and a few machine-dependent functions. This section explains how
  74. \fBceg\fR works. The first half describes the transformations that are done on
  75. the two tables. The
  76. second half tells how these transformations are done by the \fBceg\fR.
  77. .PP
  78. A code expander consists of a set of routines that convert EM-instructions
  79. directly to relocatable object code. These routines are called by a front
  80. end through the EM_CODE(3ACK)
  81. .[
  82. EM_CODE
  83. .]
  84. interface. To free the table writer of the burden of building
  85. an object file, we supply a set of routines that build an object file
  86. in the ACK.OUT(5ACK)
  87. .[
  88. aout
  89. .]
  90. format (see appendix B). This set of routines is called
  91. the
  92. \fBback\fR-primitives (see appendix A). In short, a code expander consists of a
  93. set of routines that map the EM_CODE interface on the
  94. \fBback\fR-primitives interface.
  95. .PP
  96. To avoid repetition of the same sequences of
  97. \fBback\fR-primitives in different
  98. EM-instructions
  99. and to improve readability, the EM-to-object information must be supplied in
  100. two
  101. tables. The EM_table maps EM to an assembly language, and the as_table
  102. maps
  103. assembly code to \fBback\fR-primitives. The assembly language is chosen by the
  104. table writer. It can either be an actual assembly language or his ad-hoc
  105. designed language.
  106. .LP
  107. The following picture shows the dependencies between the different components:
  108. .sp
  109. .PS
  110. linewid = 0.5i
  111. A: line down 2i
  112. B: line down 2i with .start at A.start + (1.5i, 0)
  113. C: line down 2i with .start at B.start + (1.5i, 0)
  114. D: arrow right with .start at A.center - (0.25i, 0)
  115. E: arrow right with .start at B.center - (0.25i, 0)
  116. F: arrow right with .start at C.center - (0.25i, 0)
  117. "EM_CODE(3ACK)" at A.start above
  118. "EM_table" at B.start above
  119. "as_table" at C.start above
  120. "source language " at D.start rjust
  121. "EM" at 0.5 of the way between D.end and E.start
  122. G: "assembly" at 0.5 of the way between E.end and F.start
  123. H: " back primitives" at F.end ljust
  124. "(user defined)" at G - (0, 0.2i)
  125. " (ACK.OUT)" at H - (0, 0.2i) ljust
  126. .PE
  127. .PP
  128. The picture suggests that, during compilation, the EM instructions are
  129. first transformed into assembly instructions and then the assembly instructions
  130. are transformed into object-generating calls. This
  131. is not what happens in practice, although the user is free to think it does.
  132. Actually, however the EM_table and the as_table are combined during code
  133. expander generation time, yielding an imaginary compound table that results in
  134. routines from the EM_CODE interface that generate object code directly.
  135. .PP
  136. As already indicated, the compound table does not exist either. Instead, each
  137. assembly instruction in the as_table is converted to a routine generating C
  138. .[
  139. Kernighan
  140. .]
  141. code
  142. to generate C code to call the \fBback\fR-primitives. The EM_table is
  143. converted into a program that for each EM instruction generates a routine,
  144. using the routines generated from the as_table. Execution of the latter program
  145. will then generate the code expander.
  146. .PP
  147. This scheme allows great flexibility
  148. in the table writing, while still
  149. resulting in a very efficient code expander. One implication is that the
  150. as_table is interpreted twice and the EM_table only once. This has consequences
  151. for their structure.
  152. .PP
  153. To illustrate what happens, we give an example. The example is an entry in
  154. the tables for the VAX-machine. The assembly language chosen is a subset of the
  155. VAX assembly language.
  156. .PP
  157. One of the most fundamental operations in EM is ``loc c'', load the value of c
  158. on the stack. To expand this instruction the
  159. tables contain the following information:
  160. .DS
  161. EM_table :
  162. .ft CW
  163. C_loc ==> "pushl $$$1".
  164. /* $1 refers to the first argument of C_loc.
  165. * $$ is a quoted $. */
  166. \fRas_table :
  167. .ft CW
  168. pushl src : CONST ==>
  169. @text1( 0xd0);
  170. @text1( 0xef);
  171. @text4( %$( src->num)).
  172. \fR
  173. .DE
  174. .LP
  175. The as_table is transformed in the following routine:
  176. .DS
  177. .ft CW
  178. pushl_instr(src)
  179. t_operand *src;
  180. /* ``t_operand'' is a struct defined by the
  181. * table writer. */
  182. {
  183. printf("swtxt();");
  184. printf("text1( 0xd0 );");
  185. printf("text1( 0xef );");
  186. printf("text4(%s);", substitute_dollar( src->num));
  187. }
  188. \fR
  189. .DE
  190. Using ``pushl_instr()'', the following routine is generated from the EM_table:
  191. .DS
  192. .ft CW
  193. C_loc( c)
  194. arith c;
  195. /* text1() and text4() are library routines that fill the
  196. * text segment. */
  197. {
  198. swtxt();
  199. text1( 0xd0);
  200. text1( 0xef);
  201. text4( c);
  202. }
  203. \fR
  204. .DE
  205. .LP
  206. A compiler call to ``C_loc()'' will cause the 1-byte numbers ``0xd0''
  207. and ``0xef''
  208. and the 4-byte value of the variable ``c'' to be stored in the text segment.
  209. .PP
  210. The transformations on the tables are done automatically by the code expander
  211. generator.
  212. The code expander generator is made up of two tools:
  213. \fBemg\fR and \fBasg\fR. \fBAsg\fR
  214. transforms
  215. each assembly instruction into a C routine. These C routines generate calls
  216. to the \fBback\fR-primitives. The generated C routines are used
  217. by \fBemg\fR to generate the actual code expander from the EM_table.
  218. .PP
  219. The link between \fBemg\fR and \fBasg\fR is an assembly language.
  220. We did not enforce a specific syntax for the assembly language;
  221. instead we have given the table writer the freedom
  222. to make an ad-hoc assembly language or to use an actual assembly language
  223. suitable for his purpose. Apart from a greater flexibility this
  224. has another advantage; if the table writer adopts the assembly language that
  225. runs on the machine at hand, he can test the EM_table independently from the
  226. as_table. Of course there is a price to pay: the table writer has to
  227. do the decoding of the operands himself. See section 4 for more details.
  228. .PP
  229. Before we describe the structure of the tables in detail, we will give
  230. an overview of the four main phases.
  231. .IP "phase 1:"
  232. .br
  233. The as_table is transformed by \fBasg\fR. This results in a set of C routines.
  234. Each assembly-opcode generates one C routine. Note that a call to such a
  235. routine does not generate the corresponding object code; it generates C code,
  236. which, when executed, generates the desired object code.
  237. .IP "phase 2:"
  238. .br
  239. The C routines generated by \fBasg\fR are used by emg to expand the EM_table.
  240. This
  241. results in a set of C routines, the code expander, which conform to the
  242. procedural interface EM_CODE(3ACK). A call to such a routine does indeed
  243. generate the desired object code.
  244. .IP "phase 3:"
  245. .br
  246. The front end that uses the procedural interface is linked/loaded with the
  247. code expander generated in phase 2 and the \fBback\fR-primitives (a supplied
  248. library). This results in a compiler.
  249. .IP "phase 4:"
  250. .br
  251. The compiler runs. The routines in the code expander are
  252. executed and produce object code.
  253. .RE
  254. .NH
  255. Description of the EM_table
  256. .PP
  257. This section describes the EM_table. It contains four subsections.
  258. The first 3 sections describe the syntax of the EM_table,
  259. the
  260. semantics of the EM_table, and the functions and
  261. constants that must be present in the EM_table, in the file ``mach.c'' or in
  262. the file ``mach.h''. The last section explains how a table writer can generate
  263. assembly code instead of object code. The section on
  264. semantics contains many examples.
  265. .NH 2
  266. Grammar
  267. .PP
  268. The following grammar describes the syntax of the EM_table.
  269. .VS +4
  270. .TS
  271. center tab(%);
  272. l c l.
  273. TABLE%::=%( RULE)*
  274. RULE%::=%C_instr ( COND_SEQUENCE | SIMPLE)
  275. COND_SEQUENCE%::=%( condition SIMPLE)* ``default'' SIMPLE
  276. SIMPLE%::=% ``==>'' ACTION_LIST
  277. ACTION_LIST%::=%[ ACTION ( ``;'' ACTION)* ] ``.''
  278. ACTION%::=%AS_INSTR
  279. %|%function-call
  280. AS_INSTR%::=%``"'' [ label ``:''] [ INSTR] ``"''
  281. INSTR%::=%mnemonic [ operand ( ``,'' operand)* ]
  282. .TE
  283. .VS -4
  284. .PP
  285. The ``('' ``)'' brackets are used for grouping, ``['' ... ``]''
  286. means ... 0 or 1 time,
  287. a ``*'' means zero or more times, and
  288. a ``|'' means
  289. a choice between left or right. A \fBC_instr\fR is
  290. a name in the EM_CODE(3ACK) interface. \fBcondition\fR is a C expression.
  291. \fBfunction-call\fR is a call of a C function. \fBlabel\fR, \fBmnemonic\fR,
  292. and \fBoperand\fR are arbitrary strings. If an \fBoperand\fR
  293. contains brackets, the
  294. brackets must match. There is an upper bound on the number of
  295. operands; the maximum number is defined by the constant MAX_OPERANDS in de
  296. file ``const.h'' in the directory assemble.c. Comments in the table should be
  297. placed between ``/*'' and ``*/''.
  298. The table is processed by the C preprocessor, before being parsed by
  299. \fBemg\fR.
  300. .NH 2
  301. Semantics
  302. .PP
  303. The EM_table is processed by \fBemg\fR. \fBEmg\fR generates a C function
  304. for every instruction in the EM_CODE(3ACK).
  305. For every EM-instruction not mentioned in the EM_table, a
  306. C function that prints an error message is generated.
  307. It is possible to divide the EM_CODE(3ACK)-interface into four parts :
  308. .IP \0\01:
  309. text instructions (e.g., C_loc, C_adi, ..)
  310. .IP \0\02:
  311. pseudo instructions (e.g., C_open, C_df_ilb, ..)
  312. .IP \0\03:
  313. storage instructions (e.g., C_rom_icon, ..)
  314. .IP \0\04:
  315. message instructions (e.g., C_mes_begin, ..)
  316. .LP
  317. This section starts with giving the semantics of the grammar. The examples
  318. are text instructions. The section ends with remarks on the pseudo
  319. instructions and the storage instructions. Since message instructions are not
  320. useful for a code expander, they are ignored.
  321. .PP
  322. .NH 3
  323. Actions
  324. .PP
  325. The EM_table is made up of rules describing how to expand a \fBC_instr\fR
  326. defined by the EM_CODE(3ACK)-interface (corresponding
  327. to an EM instruction) into actions.
  328. There are two kinds of actions: assembly instructions and C function calls.
  329. An assembly instruction is defined as a mnemonic followed by zero or more
  330. operands separated by commas. The semantics of an assembly instruction is
  331. defined by the table writer. When the assembly language is not expressive
  332. enough, then, as an escape route, function calls can be made. However, this
  333. reduces
  334. the speed of the actual code expander. Finally, actions can be grouped into
  335. a list of actions; actions are separated by a semicolon and terminated
  336. by a ``.''.
  337. .DS
  338. .ft CW
  339. C_nop ==> .
  340. /* Empty action list : no operation. */
  341. C_inc ==> "incl (sp)".
  342. /* Assembler instruction, which is evaluated
  343. * during expansion of the EM_table */
  344. C_slu ==> C_sli( $1).
  345. /* Function call, which is evaluated during
  346. * execution of the compiler. */
  347. \fR
  348. .DE
  349. .NH 3
  350. Labels
  351. .PP
  352. Since an assembly language without instruction labels is a rather weak
  353. language, labels inside a contiguous block of assembly instructions are
  354. allowed. When using labels two rules must be observed:
  355. .IP \0\01:
  356. The name of a label should be unique inside an action list.
  357. .IP \0\02:
  358. The labels used in an assembler instruction should be defined in the same
  359. action list.
  360. .LP
  361. The following example illustrates the usage of labels.
  362. .DS
  363. .ft CW
  364. /* Compare the two top elements on the stack. */
  365. C_cmp ==> "pop bx";
  366. "pop cx";
  367. "xor ax, ax";
  368. "cmp cx, bx";
  369. /* Forward jump to local label */
  370. "je 2f";
  371. "jb 1f";
  372. "inc ax";
  373. "jmp 2f";
  374. "1: dec ax";
  375. "2: push ax".
  376. \fR
  377. .DE
  378. We will come back to labels in the section on the as_table.
  379. .NH 3
  380. Arguments of an EM instruction
  381. .PP
  382. In most cases the translation of a \fBC_instr\fR depends on its arguments.
  383. The arguments of a \fBC_instr\fR are numbered from 1 to \fIn\fR, where \fIn\fR
  384. is the
  385. total number of arguments of the current \fBC_instr\fR (there are a few
  386. exceptions, see Implicit arguments). The table writer may
  387. refer to an argument as $\fIi\fR. If a plain $-sign is needed in an
  388. assembly instruction, it must be preceded by a extra $-sign.
  389. .PP
  390. There are two groups of \fBC_instr\fRs whose arguments are handled specially:
  391. .RS
  392. .IP "1: Instructions dealing with local offsets"
  393. .br
  394. The value of the $\fIi\fR argument referring to a parameter ($\fIi\fR >= 0)
  395. is increased by ``EM_BSIZE''. ``EM_BSIZE'' is the size of the return status block
  396. and must be defined in the file ``mach.h'' (see section 3.3). For example :
  397. .DS
  398. .ft CW
  399. C_lol ==> "push $1(bp)".
  400. /* automatic conversion of $1 */
  401. \fR
  402. .DE
  403. .IP "2: Instructions using global names or instruction labels"
  404. .br
  405. All the arguments referring to global names or instruction labels will be
  406. transformed into a unique assembly name. To prevent name clashes with library
  407. names the table writer has to provide the
  408. conversions in the file ``mach.h''. For example :
  409. .DS
  410. .ft CW
  411. C_bra ==> "jmp $1".
  412. /* automatic conversion of $1 */
  413. /* type arith is converted to string */
  414. \fR
  415. .DE
  416. .RE
  417. .NH 3
  418. Conditionals
  419. .PP
  420. The rules in the EM_table can be divided into two groups: simple rules and
  421. conditional rules. The simple rules are made up of a \fBC_instr\fR followed by
  422. a list of actions, as described above. The conditional rules (COND_SEQUENCE)
  423. allow the table writer to select an action list depending on the value of
  424. a condition.
  425. .PP
  426. A CONDITIONAL is a list of a boolean expression with the corresponding
  427. simple rule. If
  428. the expression evaluates to true then the corresponding simple rule is carried
  429. out. If more than one condition evaluates to true, the first one is chosen.
  430. The last case of a COND_SEQUENCE of a \fBC_instr\fR must handle
  431. the default case.
  432. The boolean expressions in a COND_SEQUENCE must be C expressions. Besides the
  433. ordinary C operators and constants, $\fIi\fR references can be used
  434. in an expression.
  435. .DS
  436. .ft CW
  437. /* Load address of LB $1 levels back. */
  438. C_lxl
  439. $1 == 0 ==> "pushl fp".
  440. $1 == 1 ==> "pushl 4(ap)".
  441. default ==> "movl $$$1, r0";
  442. "jsb .lxl";
  443. "pushl r0".
  444. \fR
  445. .DE
  446. .NH 3
  447. Abbreviations
  448. .PP
  449. EM instructions with an external as an argument come in three variants in
  450. the EM_CODE(3ACK) interface. In most cases it will be possible to take
  451. these variants together. For this purpose the ``..'' notation is introduced.
  452. For the code expander there is no difference between the
  453. following instructions.
  454. .DS
  455. .ft CW
  456. C_loe_dlb ==> "pushl $1 + $2".
  457. C_loe_dnam ==> "pushl $1 + $2".
  458. C_loe ==> "pushl $1 + $2".
  459. \fR
  460. .DE
  461. So it can be written in the following way.
  462. .DS
  463. .ft CW
  464. C_loe.. ==> "pushl $1 + $2".
  465. \fR
  466. .DE
  467. .NH 3
  468. Implicit arguments
  469. .PP
  470. In the last example ``C_loe'' has two arguments, but in the EM_CODE interface
  471. it has one argument. This argument depends on the current ``hol''
  472. block; in the EM_table this is made explicit. Every \fBC_instr\fR whose
  473. argument depends on a ``hol'' block has one extra argument; argument 1 refers
  474. to the ``hol'' block.
  475. .NH 3
  476. Pseudo instructions
  477. .PP
  478. Most pseudo instructions are machine independent and are provided
  479. by \fBceg\fR. The table writer has only to supply the following functions,
  480. which are used to build a stackframe:
  481. .DS
  482. .ft CW
  483. C_prolog()
  484. /* Performs the prolog, for example save
  485. * return address */
  486. C_locals( n)
  487. arith n;
  488. /* Allocate n bytes for locals on the stack */
  489. C_jump( label)
  490. char *label;
  491. /* Generates code for a jump to ``label'' */
  492. \fR
  493. .DE
  494. .LP
  495. These functions can be defined in ``mach.c'' or in the EM_table (see
  496. section 3.3).
  497. .NH 3
  498. Storage instructions
  499. .PP
  500. The storage instructions ``C_bss_\fIcstp()\fR'', ``C_hol_\fIcstp()\fR'',
  501. ''C_con_\fIcstp()\fR'', and ``C_rom_\fIcstp()\fR'', except for the instructions
  502. dealing with constants of type string (C_..._icon, C_..._ucon, C_..._fcon), are
  503. generated automatically. No information is needed in the table.
  504. To generate the C_..._icon, C_..._ucon, C_..._fcon instructions
  505. \fBceg\fR only has to know how to convert a number of type string to bytes;
  506. this can be defined with the constants ONE_BYTE, TWO_BYTES, and FOUR_BYTES.
  507. C_rom_icon, C_con_icon, C_bss_icon, C_hol_icon can be abbreviated by ..icon.
  508. This also holds for ..ucon and ..fcon.
  509. For example :
  510. .DS
  511. .ft CW
  512. \\.\\.icon
  513. $2 == 1 ==> gen1( (ONE_BYTE) atoi( $1)).
  514. $2 == 2 ==> gen2( (TWO_BYTES) atoi( $1)).
  515. $2 == 4 ==> gen4( (FOUR_BYTES) atol( $1)).
  516. default ==> arg_error( "..icon", $2).
  517. \fR
  518. .DE
  519. Gen1(), gen2() and gen4() are \fBback\fR-primitives (see appendix A), and
  520. generate one, two, or four byte constants. Atoi() is a C library function that
  521. converts strings to integers.
  522. The constants ``ONE_BYTE'', ``TWO_BYTES'', and ``FOUR_BYTES'' must be defined in
  523. the file ``mach.h''.
  524. .NH 2
  525. User supplied definitions and functions
  526. .PP
  527. If the table writer uses all the default functions he has only to supply
  528. the following constants and functions :
  529. .TS
  530. tab(#);
  531. l c lw(10c).
  532. C_prolog()#:#T{
  533. Do prolog
  534. T}
  535. C_jump( l)#:#T{
  536. Perform a jump to label l
  537. T}
  538. C_locals( n)#:#T{
  539. Allocate n bytes on the stack
  540. T}
  541. #
  542. NAME_FMT#:#T{
  543. Print format describing name to a unique name conversion. The format must
  544. contain %s.
  545. T}
  546. DNAM_FMT#:#T{
  547. Print format describing data-label to a unique name conversion. The format
  548. must contain %s.
  549. T}
  550. DLB_FMT#:#T{
  551. Print format describing numerical-data-label to a unique name conversion.
  552. The format must contain a %ld.
  553. T}
  554. ILB_FMT#:#T{
  555. Print format describing instruction-label to a unique name conversion.
  556. The format must contain %d followed by %ld.
  557. T}
  558. HOL_FMT#:#T{
  559. Print format describing hol-block-number to a unique name conversion.
  560. The format must contain %d.
  561. T}
  562. #
  563. EM_WSIZE#:#T{
  564. Size of a word in bytes on the target machine
  565. T}
  566. EM_PSIZE#:#T{
  567. Size of a pointer in bytes on the target machine
  568. T}
  569. EM_BSIZE#:#T{
  570. Size of base block in bytes on the target machine
  571. T}
  572. #
  573. ONE_BYTE#:#T{
  574. \\C suitable type that can hold one byte on the machine where the \fBce\fR runs
  575. T}
  576. TWO_BYTES#:#T{
  577. \\C suitable type that can hold two bytes on the machine where the \fBce\fR runs
  578. T}
  579. FOUR_BYTES#:#T{
  580. \\C suitable type that can hold four bytes on the machine where the \fBce\fR runs
  581. T}
  582. #
  583. BSS_INIT#:#T{
  584. The default value that the loader puts in the bss segment
  585. T}
  586. #
  587. BYTES_REVERSED#:#T{
  588. Must be defined if the byte order must be reversed.
  589. By default the least significant byte is outputted first.\fR\(dg
  590. .FS
  591. \fR\(dg When both byte orders are used, for
  592. example NS 16032, the table writer has to
  593. supply his own set of routines.
  594. .FE
  595. T}
  596. WORDS_REVERSED#:#T{
  597. Must be defined if the word order must be reversed.
  598. By default the least significant word is outputted first.
  599. T}
  600. .TE
  601. .LP
  602. An example of the file ``mach.h'' for the vax4.
  603. .TS
  604. tab(:);
  605. l l l.
  606. #define : ONE_BYTE : int
  607. #define : TWO_BYTES : int
  608. #define : FOUR_BYTES : long
  609. :
  610. #define : EM_WSIZE : 4
  611. #define : EM_PSIZE : 4
  612. #define : EM_BSIZE : 0
  613. :
  614. #define : BSS_INIT : 0
  615. :
  616. #define : NAME_FMT : "_%s"
  617. #define : DNAM_FMT : "_%s"
  618. #define : DLB_FMT : "_%ld"
  619. #define : ILB_FMT : "I%03d%ld"
  620. #define : HOL_FMT : "hol%d"
  621. .TE
  622. Notice that EM_BSIZE is zero. The vax ``call'' instruction takes automatically
  623. care of the base block.
  624. .PP
  625. There are three primitives that have to be defined by the table writer, either
  626. as functions in the file ``mach.c'' or as rules in the EM_table.
  627. For example, for the 8086 they look like this:
  628. .DS
  629. .ft CW
  630. C_jump ==> "jmp $1".
  631. C_prolog ==> "push bp";
  632. "mov bp, sp".
  633. C_locals
  634. $1 == 0 ==> .
  635. $1 == 2 ==> "push ax".
  636. $1 == 4 ==> "push ax";
  637. "push ax".
  638. default ==> "sub sp, $1".
  639. \fR
  640. .DE
  641. .NH 2
  642. Generating assembly code
  643. .PP
  644. When the code expander generator is used for generating assembly instead of
  645. object code (see section 5), additional print formats have to be defined
  646. in ``mach.h''. The following table lists these formats.
  647. .TS
  648. tab(#);
  649. l c lw(10c).
  650. BYTE_FMT#:#T{
  651. Print format to allocate and initialize one byte. The format must
  652. contain %ld.
  653. T}
  654. WORD_FMT#:#T{
  655. Print format to allocate and initialize one word. The format must
  656. contain %ld.
  657. T}
  658. LONG_FMT#:#T{
  659. Print format to allocate and initialize one long. The format must
  660. contain %ld.
  661. T}
  662. BSS_FMT#:#T{
  663. Print format to allocate space in the bss segment. The format must
  664. contain %ld (number of bytes).
  665. T}
  666. COMM_FMT#:#T{
  667. Print format to declare a "common". The format must contain a %s (name to be declared
  668. common), followed by a %ld (number of bytes).
  669. T}
  670. SEGTXT_FMT#:#T{
  671. Print format to switch to the text segment.
  672. T}
  673. SEGDAT_FMT#:#T{
  674. Print format to switch to the data segment.
  675. T}
  676. SEGBSS_FMT#:#T{
  677. Print format to switch to the bss segment.
  678. T}
  679. SYMBOL_DEF_FMT#:#T{
  680. Print format to define a label. The format must contain %s.
  681. T}
  682. GLOBAL_FMT#:#T{
  683. Print format to declare a global name. The format must contain %s.
  684. T}
  685. LOCAL_FMT#:#T{
  686. Print format to declare a local name. The format must contain %s.
  687. T}
  688. RELOC1_FMT#:#T{
  689. Print format to initialize a byte with an address expression. The format must
  690. contain %s (name) and %ld (offset).
  691. T}
  692. RELOC2_FMT#:#T{
  693. Print format to initialize a word with an address expression. The format must
  694. contain %s (name) and %ld (offset).
  695. T}
  696. RELOC4_FMT#:#T{
  697. Print format to initialize a long with an address expression. The format must
  698. contain %s (name) and %ld (offset).
  699. T}
  700. ALIGN_FMT#:#T{
  701. Print format to align a segment.
  702. T}
  703. .TE
  704. .NH 1
  705. Description of the as_table
  706. .PP
  707. This section describes the as_table. Like the previous section, it is divided
  708. into
  709. four parts: the first two parts describe the grammar and the semantics of the
  710. as_table; the third part gives an overview
  711. of the functions and the constants that must be present in the as_table (in
  712. the file ``as.h'' or in the file ``as.c''); the last part describes the case when
  713. assembly is generated instead of object code.
  714. The part on semantics contains examples that appear in the as_table for the
  715. VAX or for the 8086.
  716. .NH 2
  717. Grammar
  718. .PP
  719. The form of the as_table is given by the following grammar :
  720. .VS +4
  721. .TS
  722. center tab(#);
  723. l c l.
  724. TABLE#::=#( RULE)*
  725. RULE#::=#( mnemonic | ``...'') DECL_LIST ``==>'' ACTION_LIST
  726. DECL_LIST#::=#DECLARATION ( ``,'' DECLARATION)*
  727. DECLARATION#::=#operand [ ``:'' type]
  728. ACTION_LIST#::=#ACTION ( ``;'' ACTION) ``.''
  729. ACTION#::=#IF_STATEMENT
  730. #|#function-call
  731. #|#``@''function-call
  732. IF_STATEMENT#::=#''@if'' ``('' condition ``)'' ACTION_LIST
  733. ##( ``@elsif'' ``('' condition ``)'' ACTION_LIST)*
  734. ##[ ``@else'' ACTION_LIST]
  735. ##''@fi''
  736. function-call#::=#function-identifier ``('' [arg (,arg)*] ``)''
  737. arg#::=#argument
  738. #|#reference
  739. .TE
  740. .VS -4
  741. .LP
  742. \fBmnemonic\fR, \fBoperand\fR, and \fBtype\fR are all C identifiers;
  743. \fBcondition\fR is a normal C expression;
  744. \fBfunction-call\fR must be a C function call. A function can be called with
  745. standard C arguments or with a reference (see section 4.2.4).
  746. Since the as_table is
  747. interpreted during code expander generation as well as during code
  748. expander execution, two levels of calls are present in it. A ``function-call''
  749. is done during code expander generation, a ``@function-call'' during code
  750. expander execution.
  751. .NH 2
  752. Semantics
  753. .PP
  754. The as_table is made up of rules that map assembly instructions onto
  755. \fBback\fR-primitives, a set of functions that construct an object file.
  756. The table is processed by \fBasg\fR, which generates a C functions
  757. for each assembler mnemonic. The names of
  758. these functions are the assembler mnemonics postfixed
  759. with ``_instr'' (e.g., ``add'' becomes ``add_instr()''). These functions
  760. will be used by the function
  761. assemble() during the expansion of the EM_table.
  762. After explaining the semantics of the as_table the function
  763. assemble() will be described.
  764. .NH 3
  765. Rules
  766. .PP
  767. A rule in the as_table is made up of a left and a right hand side;
  768. the left hand side describes an assembler
  769. instruction (mnemonic and operands); the
  770. right hand side gives the corresponding actions as \fBback\fR-primitives or as
  771. functions defined by the table writer, which call \fBback-primitives\fR.
  772. Two simple examples from the VAX as_table and the 8086 as_table, resp.:
  773. .DS
  774. .ft CW
  775. movl src, dst ==> @text1( 0xd0);
  776. gen_operand( src);
  777. gen_operand( dst).
  778. /* ``gen_operand'' is a function that encodes
  779. * operands by calling back-primitives. */
  780. rep ens:MOVS ==> @text1( 0xf3);
  781. @text1( 0xa5).
  782. \fR
  783. .DE
  784. .NH 3
  785. Declaration of types.
  786. .PP
  787. In general, a machine instruction is encoded as an opcode followed by zero or
  788. more
  789. the operands. There are two methods for mapping assembler mnemonics
  790. onto opcodes: the mnemonic determines the opcode, or mnemonic and operands
  791. together determine the opcode. Both cases can be
  792. easily expressed in the as_table.
  793. The first case is obvious.
  794. The second case is handled by introducing type fields for the operands.
  795. .PP
  796. When mnemonic and operands together determine the opcode, the table writer has
  797. to give several rules for each combination of mnemonic and operands. The rules
  798. differ in the type fields of the operands.
  799. The table writer has to supply functions that check the type
  800. of the operand. The name of such a function is the name of the type; it
  801. has one argument: a pointer to a struct of type \fIt_operand\fR; it returns
  802. non-zero when the operand is of this type, otherwise it returns 0.
  803. .PP
  804. This will usually lead to a list of rules per mnemonic. To reduce the amount of
  805. work an abbreviation is supplied. Once the mnemonic is specified it can be
  806. referred to in the following rules by ``...''.
  807. One has to make sure
  808. that each mnemonic is mentioned only once in the as_table, otherwise
  809. \fBasg\fR will generate more than one function with the same name.
  810. .PP
  811. The following example shows the usage of type fields.
  812. .DS
  813. .ft CW
  814. mov dst:REG, src:EADDR ==>
  815. @text1( 0x8b); /* opcode */
  816. mod_RM( %d(dst->reg), src). /* operands */
  817. ... dst:EADDR, src:REG ==>
  818. @text1( 0x89); /* opcode */
  819. mod_RM( %d(src->reg), dst). /* operands */
  820. \fR
  821. .DE
  822. The table-writer must supply the restriction functions,
  823. .ft CW
  824. REG\fR and
  825. .ft CW
  826. EADDR\fR in the previous example, in ``as.c'' or ''as.h''.
  827. .NH 3
  828. The function of the @-sign and the if-statement.
  829. .PP
  830. The right hand side of a rule is made up of function calls.
  831. Since the as_table is
  832. interpreted on two levels, during code expander generation and during code
  833. expander execution, two levels of calls are present in it. A function-call
  834. without an ``@''-sign
  835. is called during code expander generation (e.g., the
  836. .ft CW
  837. gen_operand()\fR in the
  838. first example).
  839. A function call with an ``@''-sign is called during code
  840. expander execution (e.g.,
  841. the \fBback\fR-primitives). So the last group will be part of the compiler.
  842. .PP
  843. The need for the ``@''-sign construction arises, for example, when
  844. implementing push/pop optimization (e.g., ``push x'' followed by ``pop y''
  845. can be replaced by ``move x, y'').
  846. In this case flags need to be set, unset, and tested during the execution of
  847. the compiler:
  848. .DS L
  849. .ft CW
  850. PUSH src ==> /* save in ax */
  851. mov_instr( AX_oper, src);
  852. /* set flag */
  853. @assign( push_waiting, TRUE).
  854. \fR
  855. .DE
  856. .DS
  857. .ft CW
  858. POP dst ==> @if ( push_waiting)
  859. /* ``mov_instr'' is asg-generated */
  860. mov_instr( dst, AX_oper);
  861. @assign( push_waiting, FALSE).
  862. @else
  863. /* ``pop_instr'' is asg-generated */
  864. pop_instr( dst).
  865. @fi.
  866. \fR
  867. .DE
  868. .LP
  869. Although the @-sign is followed syntactically by a
  870. function name, this function can very well be the name of a macro defined in C.
  871. This is in fact the case with ``@assign()'' in the above example.
  872. .PP
  873. The case may arise when information is needed that is not known
  874. until execution of
  875. the compiler. For example one needs to know if a ``$\fIi\fR'' argument fits in
  876. one byte.
  877. In this case one can use a special if-statement provided
  878. by \fBasg\fR: @if, @elsif, @else, @fi. This means that the conditions
  879. will be evaluated at
  880. run time of the \fBce\fR. In such a condition one may of course refer
  881. to the ''$\fIi\fR'' arguments. For example, constants can be
  882. packed into one or two byte arguments as follows:
  883. .DS
  884. .ft CW
  885. mov dst:ACCU, src:DATA ==>
  886. @if ( fits_byte( %$(dst->expr)))
  887. @text1( 0xc0);
  888. @text1( %$(dst->expr)).
  889. @else
  890. @text1( 0xc8);
  891. @text2( %$(dst->expr)).
  892. @fi.
  893. .DE
  894. .NH 3
  895. References to operands
  896. .PP
  897. As noted before, the operands of an assembler instruction may be used as
  898. pointers to the struct \fIt_operand\fR in the right hand side of the table.
  899. Because of the free format assembler, the types of the fields in the struct
  900. \fIt_operand\fR are unknown to \fBasg\fR. As these fields can appear in calls
  901. to functions, \fBasg\fR must know
  902. these types. This section explains how these types must be specified.
  903. .PP
  904. References to operands come in three forms: ordinary operands, operands that
  905. contain ``$\fIi\fR'' references, and operands that refer to names of local labels.
  906. The ``$\fIi\fR'' in operands represent names or numbers of a \fBC_instr\fR and must
  907. be given as arguments to the \fBback\fR-primitives. Labels in operands
  908. must be converted to a number that tells the distance, the number of bytes,
  909. between the label and the current position in the text-segment.
  910. .LP
  911. All these three cases are treated in an uniform way. When the table writer
  912. makes a reference to an operand of an assembly instruction, he must describe
  913. the type of the operand in the following way.
  914. .VS +4
  915. .TS
  916. center tab(#);
  917. l c l.
  918. reference#::=#``%'' conversion
  919. ##``('' operand-name ``\->'' field-name ``)''
  920. conversion#::=# printformat
  921. #|#``$''
  922. #|#``dist''
  923. printformat#::=#see PRINT(3ACK)
  924. .[
  925. PRINT
  926. .]
  927. .TE
  928. .VS -4
  929. .LP
  930. The three cases differ only in the conversion field. The printformat conversion
  931. applies to ordinary operands. The ``%$'' applies to operands that contain
  932. a ``$\fIi\fR''. The expression between parentheses must result in a pointer to
  933. a char. The
  934. result of ``%$'' is of the type of ``$\fIi\fR''. The ``%dist''
  935. applies to operands that refer to a local label. The expression between
  936. the brackets must result in a pointer to a char. The result of ``%dist'' is
  937. of type arith.
  938. .PP
  939. The following example illustrates the usage of ``%$''. (For an
  940. example that illustrates the usage of ordinary fields see
  941. the section on ``User supplied definitions and functions'').
  942. .DS
  943. .ft CW
  944. jmp dst ==>
  945. @text1( 0xe9);
  946. @reloc2( %$(dst->lab), %$(dst->off), PC_REL).
  947. \fR
  948. .DE
  949. .PP
  950. A useful function concerning $\fIi\fRs is arg_type(), which takes as input a
  951. string starting with $\fIi\fR and returns the type of the \fIi\fR''th argument
  952. of the current EM-instruction, which can be STRING, ARITH or INT. One may need
  953. this function while decoding operands if the context of the $\fIi\fR does not
  954. give enough information.
  955. If the function arg_type() is used, the file
  956. arg_type.h must contain the definition of STRING, ARITH and INT.
  957. .PP
  958. %dist is only guaranteed to work when called as a parameter of text1(), text2() or text4().
  959. The goal of the %dist conversion is to reduce the number of reloc1(), reloc2()
  960. and reloc4()
  961. calls, saving space and time (no relocation at compiler run time).
  962. The following example illustrates the usage of ``%dist''.
  963. .DS
  964. .ft CW
  965. jmp dst:ILB ==> /* label in an instruction list */
  966. @text1( 0xeb);
  967. @text1( %dist( dst->lab)).
  968. ... dst:LABEL ==> /* global label */
  969. @text1( 0xe9);
  970. @reloc2( %$(dst->lab), %$(dst->off), PC_REL).
  971. \fR
  972. .DE
  973. .NH 3
  974. The functions assemble() and block_assemble()
  975. .PP
  976. The functions assemble() and block_assemble() are provided by \fBceg\fR.
  977. If, however, the table writer is not satisfied with the way they work
  978. he can
  979. supply his own assemble() or block_assemble().
  980. The default function assemble() splits an assembly string into a
  981. label, mnemonic,
  982. and operands and performs the following actions on them:
  983. .IP \0\01:
  984. It processes the local label; it records the name and current position. Thereafter it calls the function process_label() with one argument of type string,
  985. the label. The table writer has to define this function.
  986. .IP \0\02:
  987. Thereafter it calls the function process_mnemonic() with one argument of
  988. type string, the mnemonic. The table writer has to define this function.
  989. .IP \0\03:
  990. It calls process_operand() for each operand. Process_operand() must be
  991. written by the table-writer since no fixed representation for operands
  992. is enforced. It has two arguments: a string (the operand to decode)
  993. and a pointer to the struct \fIt_operand\fR. The declaration of the struct
  994. \fIt_operand\fR must be given in the
  995. file ``as.h'', and the table-writer can put all the information needed for
  996. encoding the operand in machine format in it.
  997. .IP \0\04:
  998. It examines the mnemonic and calls the associated function, generated by
  999. \fBasg\fR, with pointers to the decoded operands as arguments. This makes it
  1000. possible to use the decoded operands in the right hand side of a rule (see
  1001. below).
  1002. .LP
  1003. If the default assemble() does not work the way the table writer wants, he
  1004. can supply his own version of it. Assemble() has the following arguments:
  1005. .DS
  1006. .ft CW
  1007. assemble( instruction )
  1008. char *instruction;
  1009. \fR
  1010. .DE
  1011. \fIinstruction\fR points to a null-terminated string.
  1012. .PP
  1013. The default function block_assemble() is called with a sequence of assembly
  1014. instructions that belong to one action list. It calls assemble() for
  1015. every assembly instruction in
  1016. this block. But if a special action is
  1017. required on a block of assembly instructions, the table writer only has to
  1018. rewrite this function to get a new \fBceg\fR that obliges to his wishes.
  1019. The function block_assemble has the following arguments:
  1020. .DS
  1021. .ft CW
  1022. block_assemble( instructions, nr, first, last)
  1023. char **instruction;
  1024. int nr, first, last;
  1025. \fR
  1026. .DE
  1027. \fIInstruction\fR point to an array of pointers to strings representing
  1028. assembly instructions. \fINr\fR is
  1029. the number of instructions that must be assembled. \fIFirst\fR
  1030. and \fIlast\fR have no function in the default block_assemble(), but are
  1031. useful when optimizations are done in block_assemble().
  1032. .PP
  1033. Four things have to be specified in ``as.h'' and ``as.c''. First the user must
  1034. give the declaration of struct \fIt_operand\fR in ``as.h'', and the functions
  1035. process_operand(), process_mnemonic(), and process_label() must be given
  1036. in ``as.c''. If the right hand side of the as_table
  1037. contains function calls other than the \fBback\fR-primitives, these functions
  1038. must also be present in ``as.c''. Note that both the ``@''-sign (see 4.2.3)
  1039. and ``references'' (see 4.2.4) also work in the functions defined in ``as.c''.
  1040. .PP
  1041. The following example shows the representative and essential parts of the
  1042. 8086 ``as.h'' and ``as.c'' files.
  1043. .nr PS 10
  1044. .nr VS 12
  1045. .LP
  1046. .DS L
  1047. .ft CW
  1048. /* Constants and type definitions in as.h */
  1049. #define UNKNOWN 0
  1050. #define IS_REG 0x1
  1051. #define IS_ACCU 0x2
  1052. #define IS_DATA 0x4
  1053. #define IS_LABEL 0x8
  1054. #define IS_MEM 0x10
  1055. #define IS_ADDR 0x20
  1056. #define IS_ILB 0x40
  1057. #define AX 0
  1058. #define BX 3
  1059. #define CL 1
  1060. #define SP 4
  1061. #define BP 5
  1062. #define SI 6
  1063. #define DI 7
  1064. #define REG( op) ( op->type & IS_REG)
  1065. #define ACCU( op) ( op->type & IS_REG && op->reg == AX)
  1066. #define REG_CL( op) ( op->type & IS_REG && op->reg == CL)
  1067. #define DATA( op) ( op->type & IS_DATA)
  1068. #define LABEL( op) ( op->type & IS_LABEL)
  1069. #define ILB( op) ( op->type & IS_ILB)
  1070. #define MEM( op) ( op->type & IS_MEM)
  1071. #define ADDR( op) ( op->type & IS_ADDR)
  1072. #define EADDR( op) ( op->type & ( IS_ADDR | IS_MEM | IS_REG))
  1073. #define CONST1( op) ( op->type & IS_DATA && strcmp( "1", op->expr) == 0)
  1074. #define MOVS( op) ( op->type & IS_LABEL&&strcmp("\"movs\"", op->lab) == 0)
  1075. #define IMMEDIATE( op) ( op->type & ( IS_DATA | IS_LABEL))
  1076. struct t_operand {
  1077. unsigned type;
  1078. int reg;
  1079. char *expr, *lab, *off;
  1080. };
  1081. extern struct t_operand saved_op, *AX_oper;
  1082. \fR
  1083. .DE
  1084. .nr PS 12
  1085. .nr VS 14
  1086. .LP
  1087. .nr PS 10
  1088. .nr VS 12
  1089. .DS L
  1090. .ft CW
  1091. /* Some functions in as.c. */
  1092. #include "arg_type.h"
  1093. #include "as.h"
  1094. #define last( s) ( s + strlen( s) - 1)
  1095. #define LEFT '('
  1096. #define RIGHT ')'
  1097. #define DOLLAR '$'
  1098. process_operand( str, op)
  1099. char *str;
  1100. struct t_operand *op;
  1101. /* expr -> IS_DATA en IS_LABEL
  1102. * reg -> IS_REG en IS_ACCU
  1103. * (expr) -> IS_ADDR
  1104. * expr(reg) -> IS_MEM
  1105. */
  1106. {
  1107. char *ptr, *index();
  1108. op->type = UNKNOWN;
  1109. if ( *last( str) == RIGHT) {
  1110. ptr = index( str, LEFT);
  1111. *last( str) = '\0';
  1112. *ptr = '\0';
  1113. if ( is_reg( ptr+1, op)) {
  1114. op->type = IS_MEM;
  1115. op->expr = ( *str == '\0' ? "0" : str);
  1116. }
  1117. else {
  1118. set_label( ptr+1, op);
  1119. op->type = IS_ADDR;
  1120. }
  1121. }
  1122. else
  1123. if ( is_reg( str, op))
  1124. op->type = IS_REG;
  1125. else {
  1126. if ( contains_label( str))
  1127. set_label( str, op);
  1128. else {
  1129. op->type = IS_DATA;
  1130. op->expr = str;
  1131. }
  1132. }
  1133. }
  1134. /*********************************************************************/
  1135. mod_RM( reg, op)
  1136. int reg;
  1137. struct t_operand *op;
  1138. /* This function helps to decode operands in machine format.
  1139. * Note the $-operators
  1140. */
  1141. {
  1142. if ( REG( op))
  1143. R233( 0x3, reg, op->reg);
  1144. else if ( ADDR( op)) {
  1145. R233( 0x0, reg, 0x6);
  1146. @reloc2( %$(op->lab), %$(op->off), ABSOLUTE);
  1147. }
  1148. else if ( strcmp( op->expr, "0") == 0)
  1149. switch( op->reg) {
  1150. case SI : R233( 0x0, reg, 0x4);
  1151. break;
  1152. case DI : R233( 0x0, reg, 0x5);
  1153. break;
  1154. case BP : R233( 0x1, reg, 0x6); /* exception! */
  1155. @text1( 0);
  1156. break;
  1157. case BX : R233( 0x0, reg, 0x7);
  1158. break;
  1159. default : fprint( STDERR, "Wrong index register %d\en",
  1160. op->reg);
  1161. }
  1162. else {
  1163. @if ( fit_byte( %$(op->expr)))
  1164. switch( op->reg) {
  1165. case SI : R233( 0x1, reg, 0x4);
  1166. break;
  1167. case DI : R233( 0x1, reg, 0x5);
  1168. break;
  1169. case BP : R233( 0x1, reg, 0x6);
  1170. break;
  1171. case BX : R233( 0x1, reg, 0x7);
  1172. break;
  1173. default : fprint( STDERR, "Wrong index register %d\en",
  1174. op->reg);
  1175. }
  1176. @text1( %$(op->expr));
  1177. @else
  1178. switch( op->reg) {
  1179. case SI : R233( 0x2, reg, 0x4);
  1180. break;
  1181. case DI : R233( 0x2, reg, 0x5);
  1182. break;
  1183. case BP : R233( 0x2, reg, 0x6);
  1184. break;
  1185. case BX : R233( 0x2, reg, 0x7);
  1186. break;
  1187. default : fprint( STDERR, "Wrong index register %d\en",
  1188. op->reg);
  1189. }
  1190. @text2( %$(op->expr));
  1191. @fi
  1192. }
  1193. }
  1194. \fR
  1195. .DE
  1196. .nr PS 12
  1197. .nr VS 14
  1198. .NH 2
  1199. Generating assembly code
  1200. .PP
  1201. It is possible to generate assembly instead of object files (see section 5), in
  1202. which case there is no need to supply ``as_table'', ``as.h'', and ``as.c''.
  1203. This option is useful for debugging the EM_table.
  1204. .NH 1
  1205. Building a code expander
  1206. .PP
  1207. This section describes how to generate a code expander in two phases.
  1208. In phase one, the EM_table is
  1209. written and assembly code is generated. If the assembly code is an actual
  1210. language, the EM_table can be tested by assembling and running the generated
  1211. code.
  1212. If an ad-hoc assembly language is used by the table writer, it is not possible
  1213. to test the EM_table, but the code generated is at least in readable form.
  1214. In the second phase, the as_table is written and object code is generated.
  1215. After the generated object code is fed into the loader, it can be tested.
  1216. .NH 2
  1217. Phase one
  1218. .PP
  1219. The following is a list of instructions to make a
  1220. code expander that generates assembly instructions.
  1221. .IP \0\01:
  1222. Create a new directory.
  1223. .IP \0\02:
  1224. Create the ``EM_table'', ``mach.h'', and ``mach.c'' files; there is no need
  1225. for ``as_table'', ``as.h'', and ``as.c'' at this moment.
  1226. .IP \0\03:
  1227. type
  1228. .br
  1229. .ft CW
  1230. install_ceg -as
  1231. \fR
  1232. .br
  1233. install_ceg will create a Makefile and three directories : ceg, ce, and back.
  1234. Ceg will contain the program ceg; this program will be
  1235. used to turn ``EM_table'' into a set of C source files (in the ce directory),
  1236. one for each
  1237. EM-instruction. All these files will be compiled and put in a library called
  1238. \fBce.a\fR.
  1239. .br
  1240. The option
  1241. .ft CW
  1242. -as\fR means that a \fBback\fR-library will be
  1243. generated (in the directory ``back'') that
  1244. supports the generation of assembly language. The library is named ``back.a''.
  1245. .IP \0\04:
  1246. Link a front end, ``ce.a'', and ``back.a'' together resulting in a compiler
  1247. that generates assembly code.
  1248. .LP
  1249. If the table writer has chosen an actual assembly language, the EM_table can be
  1250. tested (e.g., by running the compiler on the EM test set). If an error occurs,
  1251. change the EM_table and type
  1252. .IP
  1253. .br
  1254. .ft CW
  1255. update_ceg\fR \fBC_instr
  1256. \fR
  1257. .br
  1258. .LP
  1259. where \fBC_instr\fR stands for the name of the erroneous EM-instruction.
  1260. If the table writer has chosen an ad-hoc assembly language, he can at least
  1261. read the generated code and look for possible errors. If an error is found,
  1262. the same procedure as described above can be followed.
  1263. .NH 2
  1264. Phase two
  1265. .PP
  1266. The next phase is to generate a \fBce\fR that produces relocatable object
  1267. code.
  1268. .IP \0\01:
  1269. Remove the ``ce'', ``ceg'', and ``back'' directories.
  1270. .IP \0\02:
  1271. Write the ``as_table'', ``as.h'', and ``as.c'' files.
  1272. .IP \0\03:
  1273. type
  1274. .sp
  1275. .ft CW
  1276. install_ceg -obj \fR
  1277. .sp
  1278. The option
  1279. .ft CW
  1280. -obj\fR means that ``back.a'' will contain a library
  1281. for generating
  1282. ACK.OUT(5ACK) object files, see appendix B.
  1283. If the writer does not want to use the default ``back.a'',
  1284. the
  1285. .ft CW
  1286. -obj\fR flag must omitted and a ``back.a'' should be supplied that
  1287. generates the generates object code in the desired format.
  1288. .IP \0\04:
  1289. Link a front end, ``ce.a'', and ``back.a'' together resulting in a compiler
  1290. that generates object code.
  1291. .LP
  1292. The as_table is ready to be tested. If an error occurs, adapt the table.
  1293. Then there are two ways to proceed:
  1294. .IP \0\01:
  1295. recompile the whole EM_table,
  1296. .sp
  1297. .ft CW
  1298. update_ceg ALL \fR
  1299. .sp
  1300. .IP \0\02:
  1301. recompile just the few EM-instructions that contained the error,
  1302. .sp
  1303. .ft CW
  1304. update_ceg \fBC_instr\fR
  1305. .sp
  1306. where \fBC_instr\fR is an erroneous EM-instruction.
  1307. This has to be done for every EM-instruction that contained the erroneous
  1308. assembly instruction.
  1309. .NH
  1310. Acknowledgements
  1311. .PP
  1312. We want to thank Henri Bal, Dick Grune, and Ceriel Jacobs for their
  1313. valuable suggestions and the critical reading of this paper.
  1314. .NH
  1315. References
  1316. .LP
  1317. .[
  1318. $LIST$
  1319. .]
  1320. .bp
  1321. .SH
  1322. Appendix A, \fRthe \fBback\fR-primitives
  1323. .PP
  1324. This appendix describes the routines available to generate relocatable
  1325. object code. If the default back.a is used, the object code is in
  1326. ACK.OUT(5ACK) format.
  1327. In de default back.a, the names defined here are remapped to more hidden names,
  1328. to avoid name conflicts with for instance names used in the front-end. This
  1329. remapping is done in an include-file, "back.h".
  1330. A user-implemented back.a should do the same thing.
  1331. .nr PS 10
  1332. .nr VS 12
  1333. .PP
  1334. .IP A1.
  1335. Text and data generation; with ONE_BYTE b; TWO_BYTES w; FOUR_BYTES l; arith n;
  1336. .VS +4
  1337. .TS
  1338. tab(#);
  1339. l c lw(10c).
  1340. text1( b)#:#T{
  1341. Put one byte in text-segment.
  1342. T}
  1343. text2( w)#:#T{
  1344. Put word (two bytes) in text-segment, byte-order is defined by
  1345. BYTES_REVERSED in mach.h.
  1346. T}
  1347. text4( l)#:#T{
  1348. Put long ( two words) in text-segment, word-order is defined by
  1349. WORDS_REVERSED in mach.h.
  1350. T}
  1351. #
  1352. con1( b)#:#T{
  1353. Same for CON-segment.
  1354. T}
  1355. con2( w)#:
  1356. con4( l)#:
  1357. #
  1358. rom1( b)#:#T{
  1359. Same for ROM-segment.
  1360. T}
  1361. rom2( w)#:
  1362. rom4( l)#:
  1363. #
  1364. gen1( b)#:#T{
  1365. Same for the current segment, only to be used in the ``..icon'', ``..ucon'', etc.
  1366. pseudo EM-instructions.
  1367. T}
  1368. gen2( w)#:
  1369. gen4( l)#:
  1370. #
  1371. bss( n)#:#T{
  1372. Put n bytes in bss-segment, value is BSS_INIT.
  1373. T}
  1374. common( n)#:#T{
  1375. If there is a saved label, generate a "common" for it, of size
  1376. n. Otherwise, it is equivalent to bss(n).
  1377. (see also the save_label routine).
  1378. T}
  1379. .TE
  1380. .VS -4
  1381. .IP A2.
  1382. Relocation; with char *s; arith o; int r;
  1383. .VS +4
  1384. .TS
  1385. tab(#);
  1386. l c lw(10c).
  1387. reloc1( s, o, r)#:#T{
  1388. Generates relocation-information for 1 byte in the current segment.
  1389. T}
  1390. ##s\0:\0the string which must be relocated
  1391. ##o\0:\0the offset in bytes from the string.
  1392. ##T{
  1393. r\0:\0relocation type. It can have the values ABSOLUTE or PC_REL. These
  1394. two constants are defined in the file ``back.h''
  1395. T}
  1396. reloc2( s, o, r)#:#T{
  1397. Generates relocation-information for 1 word in the
  1398. current segment. Byte-order according to BYTES_REVERSED in mach.h.
  1399. T}
  1400. reloc4( s, o, r)#:#T{
  1401. Generates relocation-information for 1 long in the
  1402. current segment. Word-order according to WORDS_REVERSED in mach.h.
  1403. T}
  1404. .TE
  1405. .VS -4
  1406. .IP A3.
  1407. Symbol table interaction; with int seg; char *s;
  1408. .VS +4
  1409. .TS
  1410. tab(#);
  1411. l c lw(10c).
  1412. switch_segment( seg)#:#T{
  1413. sets current segment to ``seg'', and does alignment if necessary. ``seg''
  1414. can be one of the four constants defined in ``back.h'': SEGTXT, SEGROM,
  1415. SEGCON, SEGBSS.
  1416. T}
  1417. #
  1418. symbol_definition( s)#:#T{
  1419. Define s in symbol-table.
  1420. T}
  1421. set_local_visible( s)#:#T{
  1422. Record scope-information in symbol table.
  1423. T}
  1424. set_global_visible( s)#:#T{
  1425. Record scope-information in symbol table.
  1426. T}
  1427. .TE
  1428. .VS -4
  1429. .IP A4.
  1430. Start/end actions; with char *f;
  1431. .VS +4
  1432. .TS
  1433. tab(#);
  1434. l c lw(10c).
  1435. open_back( f)#:#T{
  1436. Directs output to file ``f'', if f is the null pointer output must be given on
  1437. standard output.
  1438. T}
  1439. close_back()#:#T{
  1440. close output stream.
  1441. T}
  1442. init_back()#:#T{
  1443. Only used with user-written back-library, gives the opportunity to initialize.
  1444. T}
  1445. end_back()#:#T{
  1446. Only used with user-written back-library.
  1447. T}
  1448. .TE
  1449. .VS -4
  1450. .IP A5.
  1451. Label generation routines; with int n; arith g; char *l; These routines all
  1452. return a "char *" to a static area, which is overwritten at each call.
  1453. .VS +4
  1454. .TS
  1455. tab(#);
  1456. l c lw(10c).
  1457. extnd_pro( n)#:#T{
  1458. Label set at the end of procedure \fIn\fP, to generate space for locals.
  1459. T}
  1460. extnd_start( n)#:#T{
  1461. Label set at the beginning of procedure \fIn\fP, to jump back to after generating
  1462. space for locals.
  1463. T}
  1464. extnd_name( l)#:#T{
  1465. Create a name for a procedure named \fIl\fP.
  1466. T}
  1467. extnd_dnam( l)#:#T{
  1468. Create a name for an external variable named \fIl\fP.
  1469. T}
  1470. extnd_dlb( g)#:#T{
  1471. Create a name for numeric data label \fIg\fP.
  1472. T}
  1473. extnd_ilb( l, n)#:#T{
  1474. Create a name for instruction label \fIl\fP in procedure \fIn\fP.
  1475. T}
  1476. extnd_hol( n)#:#T{
  1477. Create a name for HOL block number \fIn\fP.
  1478. T}
  1479. extnd_part( n)#:#T{
  1480. Create a unique label for the C_insertpart mechanism.
  1481. T}
  1482. extnd_cont( n)#:#T{
  1483. Create another unique label for the C_insertpart mechanism.
  1484. T}
  1485. extnd_main( n)#:#T{
  1486. Create yet another unique label for the C_insertpart mechanism.
  1487. T}
  1488. .TE
  1489. .VS -4
  1490. .IP A6.
  1491. Some miscellaneous routines, with char *l;
  1492. .VS +4
  1493. .TS
  1494. tab(#);
  1495. l c lw(10c).
  1496. save_label( l)#:#T{
  1497. Save label \fIl\fP. Unfortunately, in EM, when a label is encountered,
  1498. it is not yet
  1499. known in which segment it will end up. The save_label/dump_label mechanism
  1500. is there to solve this problem.
  1501. T}
  1502. dump_label()#:#T{
  1503. If there is a label saved, force definition for it now.
  1504. T}
  1505. align_word()#:#T{
  1506. Align to a word boundary, if the current segment is not a text segment.
  1507. T}
  1508. .TE
  1509. .VS -4
  1510. .nr PS 12
  1511. .nr VS 14
  1512. .bp
  1513. .SH
  1514. Appendix B, description of ACK-a.out library
  1515. .PP
  1516. The object file produced by \fBce\fR is by default in ACK.OUT(5ACK)
  1517. format. The object file is made up of one header, followed by
  1518. four segment headers, followed by text, data, relocation information,
  1519. symbol table, and the string area. The object file is tuned for the ACK-LED,
  1520. so there are some special things done just before the object file is dumped.
  1521. First, four relocation records are added which contain the names of the four
  1522. segments. Second, all the local relocation is resolved. This is done by the
  1523. function do_relo(). If there is a record belonging to a local
  1524. name this address is relocated in the segment to which the record belongs.
  1525. Besides doing the local relocation, do_relo() changes the ``nami''-field
  1526. of the local relocation records. This field receives the index of one of the
  1527. four
  1528. relocation records belonging to a segment. After the local
  1529. relocation has been resolved the routine output_back() dumps the
  1530. ACK object file.
  1531. .LP
  1532. If a different a.out format is wanted, one can choose between three strategies:
  1533. .IP \ \1:
  1534. The most simple one is to use a conversion program, which converts the ACK
  1535. a.out format to the wanted a.out format. This program exists for all most
  1536. all machines on which ACK runs. However,
  1537. not all conversion programs can generate relocation information.
  1538. The disadvantage is that the compiler will become slower.
  1539. .IP \ \2:
  1540. A better solution is to change the functions output_back(), do_relo(),
  1541. open_back(), and close_back() in such a way
  1542. that they produce the wanted a.out format. This strategy saves a lot of I/O.
  1543. .IP \ \3:
  1544. If this still is not satisfactory, the
  1545. \fBback\fR-primitives can be adapted to produce the wanted a.out format.