home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / forth / compiler / fpc / source / optimiz.seq < prev    next >
Text File  |  1991-03-13  |  24KB  |  542 lines

  1. \ OPTIMIZ.SEQ     Library Optimizers for Target Compiler
  2.  
  3. ONLY FORTH ALSO COMPILER ALSO DEFINITIONS TARGET ALSO
  4.  
  5. >FORTH
  6.  
  7. FORTH
  8.  
  9. : TVER ."  8086 Version 2.06 " ;
  10. ' TVER IS TVERSION              \ install startup message
  11.  
  12. WARNING OFF                     \ NO REDEFINITION WARNING IN LIBRARY
  13. FORTH                           \ we want a Forth NOT a target variable
  14. VARIABLE IMM-HERE               \ Most recent place where immediate move
  15.                                 \ to BX was compiled
  16.  
  17. \ ***************************************************************************
  18. \ New function for END-CODE, needs to not use REVEAL
  19.  
  20. assembler also forth also
  21.  
  22. : CEND-CODE     ( -- )
  23.                 ll-global? 0=
  24.                 if      ll-errs?        \ check for local label errors
  25.                 then
  26.                 ARUNSAVE IS RUN
  27.                 PREVIOUS A; ;
  28.  
  29. previous previous target
  30.  
  31. : %END-MACRO    ( -- )          \ complete assembly of a MACRO
  32.                 ?reopt
  33.                 [assembler]
  34.                 compile a;                      \ make sure assembler is done
  35.                 compile cend-code               \ pop assembler vocabulary
  36.                 [compile] FOR; ;                \ complete colon def
  37.  
  38. ' %END-MACRO IS END-MACRO       \ install in END-MACRO
  39.  
  40. : %END-LCODE    ( -- )          \ complete assembly of a LCODE
  41.                 ?reopt
  42.                 [assembler]
  43.                 compile a;                      \ make sure assembler is done
  44.                 compile cend-code               \ pop assembler vocabulary
  45.                 [compile] FOR; ;                \ complete colon def
  46.  
  47. ' %END-LCODE IS END-LCODE       \ install in END-LCODE
  48.  
  49. : %END-L:       ( -- )          \ complete a library CALL definition
  50.                 [assembler]
  51.                 compile setassem
  52.                 compile ret
  53.                 compile a;                      \ make sure assembler is done
  54.                 compile cend-code               \ pop assembler vocabulary
  55.                 compile unnest ;                \ complete colon def
  56.  
  57. ' %END-L: IS END-L:
  58.  
  59. : %END-LM:      ( -- )          \ complete a library MACRO : definition
  60.                 [assembler]
  61.                 compile setassem
  62.                 compile cend-code
  63.                 compile unnest ;                \ complete colon def
  64.  
  65. ' %END-LM: IS END-LM:
  66.  
  67. : %END-T:       ( -- )          \ complete a target CALL definition
  68.                 [assembler]
  69.                 setassem                \ do assembler setup
  70.                 ret a;                  \ terminate with a RET instruction
  71.                 fend-code ;             \ do assembler finishup
  72.  
  73. ' %END-T: IS END-T:
  74.  
  75. ' NOOP IS START-T:              \ no start needed in CALL threaded system
  76.  
  77. : %COMP_CALL    ( a1 -- )                       \ a1 = CFA of symbol
  78.                 232 C,-T                        \ compile CALL
  79.                 dup     >resaddr @ dup -1 <>    \ if resolved already
  80.                 if      here-t 2+ - ,-T         \ resolve this call
  81.                         >count incr             \ bump use count
  82.                                         \ ELSE, add it to the chain of
  83.                 else    drop                    \ discard the "-1"
  84.                                                 \ references to be resolved.
  85.                         dup >chain @ ,-T        \ link chain @ to here
  86.                         here-t 2- over >chain ! \ link here into chain
  87.                         >res                    \ add to resolution stack
  88.                 then    ;
  89.  
  90. ' %COMP_CALL IS COMP_CALL
  91.  
  92. : %COMP_JMP_IMM ( a1 -- )                      \ a1 = actual address
  93.                 233 C,-T HERE-T 2+ - ,-T ;
  94.  
  95. ' %COMP_JMP_IMM IS COMP_JMP_IMM
  96.  
  97. : %SUB_RET      ( -- )
  98.                 -1 ALLOT-T ;            \ remove a one byte RET instruction
  99.                                         \ preceeding us in memory
  100.  
  101. ' %SUB_RET IS SUB_RET
  102.  
  103. : %TCODE-START  ( -- )
  104.                 setassem
  105.                 init_labels ;           \ ********* 01/29/91
  106.  
  107. ' %TCODE-START IS TCODE-START
  108.  
  109. : %LCODE-START  ( -- )
  110.                 compile tcode-start     \ initialize the assembler
  111.                 assembler ;             \ and select assembler vocabulary now!
  112.  
  113. ' %LCODE-START IS LCODE-START
  114.  
  115. : %MACRO-START  ( -- )
  116.                 compile setassem        \ initialize the assembler
  117.                 assembler ;             \ and select assembler vocabulary now!
  118.  
  119. ' %MACRO-START IS MACRO-START
  120.  
  121. \ ***************************************************************************
  122. \ Start of the set of functions supported in the target compiler.
  123. \ These are mostely macros which will compile in-line assembly code.
  124. \ Colon definitions are compiled as routines when defined, and are
  125. \ accessed by a CALL when referenced.
  126.  
  127. ONLY FORTH ALSO COMPILER ALSO HTARGET ALSO TARGET ALSO DEFINITIONS
  128. ASSEMBLER ALSO
  129.  
  130. >LIBRARY                        \ Select the Library versions of
  131.                                 \ defining words.
  132.  
  133. \ ***************************************************************************
  134. \ DONOT CHANGE the first three instructions of SYSINIT. The ADD instruction
  135. \ must be HOT patched by the image save routine so DS will be set properly
  136. \ when the image loads in. The $E4F6 value is verified by the patch routine
  137. \ to make sure the code has not changed. It is then replaced with the proper
  138. \ value to add to AX so DS will be correct.
  139.  
  140. VARIABLE DP                     \ DP is really a variable that always exists,
  141.                                 \ and is always at address DATA-START.
  142. DP [FORTH] DROP [TARGET]        \ allocate it NOW to assure it's at
  143.                                 \ the beginning.
  144.  
  145. VARIABLE RP0
  146. VARIABLE SP0
  147. VARIABLE 'TIB
  148.  
  149. MACRO IMAGE-INIT ( -- )         \ Target compiler runtime initialization
  150.                 [ASSEMBLER]
  151.  
  152. \   **********   DON'T CHANGE THE NEXT EIGHT LINES  **********
  153.  
  154.                 MOV AX, CS              \ get a copy of the CODE segment
  155.                 ADD AX, # $E4F6 a;      \ patched later to adjust for
  156.                                         \ where the data really is.
  157.                 here-t 2- =: data-seg+  \ set patch pointer
  158.                 MOV DS, AX      a;      \ Set the data segment
  159.                                         \ down 256 bytes from call stack
  160.  
  161. \   **********************************************************
  162.  
  163.                 [FORTH]
  164.                 ram-seg -1 <>           \ is this a romable system
  165.                 IF                      \ if it is, include the code to
  166.                                         \ move rom data into ram
  167.                         [ASSEMBLER]
  168.                         MOV CX, DATA-START      \ DATA-START = HERE
  169.                         MOV AX, # RAM-SEG
  170.                         MOV ES, AX              \ ES = RAM-SEG
  171.                         SUB SI, SI
  172.                         SUB DI, DI              \ clear DI, and SI
  173.                         MOVSB   REP             \ move ROM into RAM
  174.                         MOV AX, ES
  175.                         MOV DS, AX              \ reset DS to ES=RAM
  176.                         [FORTH]
  177.                 THEN
  178.                 [ASSEMBLER]
  179.                 MOV SS, AX              \ set hardware stack segment to DS
  180.                 MOV AX, # RPTOP
  181.                 MOV SP, AX              \ set hardware stack register
  182.                 MOV RP0 AX              \ set Forth return stack top variable
  183.                 MOV AX, # RPTOP RPSIZE -
  184.                 MOV SI, AX              \ set data stack
  185.                 MOV 'TIB AX             \ init 'TIB to two bytes above SP0
  186.                 MOV 0 [SI], # 0 WORD    \ Initialize data stack with a zero
  187.                 SUB AX, # 2
  188.                 MOV SP0 AX              \ set Forth data stack top variable
  189.                 MOV BX, # 0             \ and top of stack register with zero
  190.                 MOV BP, BX              \ !!!!!BP WILL ALWAYS BE ZERO!!!!!
  191.                 CALL L$                 \ CALL default initialization program
  192.                 CALL L$                 \ CALL real program (gets patched)
  193.                 here-t 2- =: cold_start \ set patch pointer
  194.                 SUB AX, AX
  195.                 MOV DX, AX
  196.                 INT $21                 \ terminate back to DOS
  197.        L$: L$:  END-MACRO
  198.  
  199. FORTH DEFINITIONS               >FORTH
  200.  
  201. DEFER DEF-INIT                  \ default target initialization
  202. DEFER NO-INIT                   \ default NO initialization
  203.  
  204. : TARGET-INIT   ( -- )          \ initialize the terget compiler
  205.                 ?LIB ABORT" Cant use TARGET-INIT in a library routine"
  206.                 ONLY FORTH ALSO COMPILER ALSO
  207.                 TARGET ALSO DEFINITIONS ASSEMBLER ALSO
  208.                                 \ ************ 01/29/91
  209.                 $100 org        \ 8086 code starts at $0100 in code segment
  210.                 $02 dorg        \ 8086 data starts at $0000 in data segment
  211.                                 \ but DP is there, and more are at $0002
  212.                 tseg_init       \ Initialize the target compile buffer
  213.                 >target         \ select target defining words
  214.                 target          \ Select the target vocabulary
  215.                 F['] IMAGE-INIT                 \ address of init routine
  216.                 DUP >COUNT INCR                 \ mark it used and
  217.                         >EXECUTE EXECUTE        \ compile it
  218.                 ?DEFINIT
  219.                 IF      DEF-INIT
  220.                 ELSE    NO-INIT
  221.                 THEN    ; IMMEDIATE
  222.  
  223. ' TARGET-INIT IS TARGET-INITIALIZE
  224.  
  225. ASSEMBLER DEFINITIONS FORTH     >LIBRARY
  226.  
  227. \ ***************************************************************************
  228. \                           OPTIMIZERS !!
  229. \ ***************************************************************************
  230. \ Optimizer for the ! (store) MACRO. Looks for the following instruction
  231. \ sequence:
  232. \               DEC SI
  233. \               DEC SI
  234. \               MOV 0 [SI], BX
  235. \               MOV BX, # xxxx
  236. \               LODSW
  237. \               MOV 0 [BX], AX
  238. \
  239. \ When these instructions are found preceeding a store instruction, they
  240. \ are changed to:
  241. \               MOV AX, BX
  242. \               MOV xxxx ax
  243. \
  244. \ This provides a substantial savings in both space and time.
  245.  
  246. FORTH   >FORTH
  247.  
  248.  
  249. : STORE_OPT     ( -- )          \ The ! MACRO
  250.                 A; [FORTH]
  251.                 ?OPT            \ Are we optimizing?
  252.         IF                                      \ instructions before ?
  253.                 HERE-T 7 -  @-T $4E4E =         \ DEC SI  DEC SI
  254.                 HERE-T 5 -  @-T $1C89 = AND     \ MOV 0 [SI], BX
  255.                 HERE-T 3 - C@-T $BB   = AND     \ MOV BX, # xxxx
  256.                 OPT_LIMIT HERE-T 7 - U< AND
  257.                 IF      HERE-T 2- @-T           \ get the address xxxx
  258.                         -7 ALLOT-T              \ if it matches, discard
  259.                                                 \ previously compiled 7 bytes
  260.                         LIHERE =: LINESTRT
  261.                         [ASSEMBLER]
  262.                         MOV ( xxxx ) BX A;      \ uses xxxx from above
  263.                         [FORTH]
  264.                 ELSE                            \ cant optimize, so
  265.                         [ASSEMBLER]             \ just compile the
  266.                         LODSW  A;               \ original code
  267.                         MOV 0 [BX], AX A;
  268.                         [FORTH]
  269.                 THEN
  270.         ELSE    ?REOPT
  271.                 [ASSEMBLER]
  272.                 LODSW A;
  273.                 MOV 0 [BX], AX A;
  274.                 [FORTH]
  275.         THEN
  276.                 [TARGET]
  277.                 ;
  278.  
  279. : CSTORE_OPT    ( -- )          \ The C! MACRO
  280.                 A; [FORTH]
  281.                 ?OPT            \ Are we optimizing?
  282.         IF                                      \ instructions before ?
  283.                 HERE-T 7 -  @-T $4E4E =         \ DEC SI  DEC SI
  284.                 HERE-T 5 -  @-T $1C89 = AND     \ MOV 0 [SI], BX
  285.                 HERE-T 3 - C@-T $BB   = AND     \ MOV BX, # xxxx
  286.                 OPT_LIMIT HERE-T 7 - U< AND
  287.                 IF      HERE-T 2- @-T           \ get the address xxxx
  288.                         -7 ALLOT-T              \ if it matches, discard
  289.                                                 \ previously compiled 7 bytes
  290.                         LIHERE =: LINESTRT
  291.                         [ASSEMBLER]
  292.                         MOV ( xxxx ) BL A;      \ uses xxxx from above
  293.                         [FORTH]
  294.                 ELSE                            \ cant optimize, so
  295.                         [ASSEMBLER]             \ just compile the
  296.                         LODSW  A;               \ original code
  297.                         MOV 0 [BX], AL A;
  298.                         [FORTH]
  299.                 THEN
  300.         ELSE    ?REOPT
  301.                 [ASSEMBLER]
  302.                 LODSW A;
  303.                 MOV 0 [BX], AL A;
  304.                 [FORTH]
  305.         THEN
  306.                 [TARGET]
  307.                 ;
  308.  
  309. \ ***************************************************************************
  310. \ A second optimizer for the ! (store) MACRO. Looks for the following
  311. \ instruction sequence:
  312. \
  313. \               DEC SI                                          3 cycles
  314. \               DEC SI                                          3 cycles
  315. \               MOV 0 [SI], BX          \ save BX              14 cycles
  316. \               MOV BX, # xxxx          \ LIT xxxx              4 cycles
  317. \               MOV yyyy BX             \ memory yyyy store     9 cycles
  318. \               LODSW                   \ load BX              12 cycles
  319. \               MOV BX, AX                                      2 cycles
  320. \
  321. \ When these instructions are found preceeding a store instruction, they
  322. \ are changed to:
  323. \
  324. \               MOV yyyy # xxxx WORD                            10 cycles
  325. \
  326. \ This provides a savings of 8 bytes and 37 cycles per occurance.
  327.  
  328. : STORE_OPT2    ( -- )          \ double optimize store immediates
  329.                 A; [FORTH]
  330.                 ?OPT            \ Are we optimizing?
  331.         IF                                      \ instructions before ?
  332.                 HERE-T 14 -  @-T $4E4E =        \ DEC SI  DEC SI
  333.                 HERE-T 12 -  @-T $1C89 = AND    \ MOV 0 [SI], BX
  334.                 HERE-T 10 - C@-T $BB   = AND    \ MOV BX, # xxxx
  335.                 HERE-T  7 -  @-T $1E89 = AND    \ MOV yyyy BX
  336.                 OPT_LIMIT HERE-T 14 - U< AND
  337.                 IF      HERE-T 5 - @-T          \ get the address yyyy
  338.                         HERE-T 9 - @-T          \ get the value xxxx
  339.                         -14 ALLOT-T             \ if it matches, discard
  340.                                                 \ previously compiled 14 bytes
  341.                         LIHERE =: LINESTRT
  342.                         [ASSEMBLER]
  343.                         MOV #  WORD     A;      \ MOV yyyy # xxxx WORD
  344.                         [FORTH]
  345.                 THEN
  346.         THEN
  347.                 [TARGET]
  348.                 ;
  349.  
  350. : STORE_OPT3    ( -- )          \ triple optimize store fetch combos
  351.                 A; [FORTH]
  352.                 ?OPT            \ Are we optimizing?
  353.         IF                                      \ instructions before ?
  354.                 HERE-T 15 -  @-T $4E4E =        \ DEC SI  DEC SI
  355.                 HERE-T 13 -  @-T $1C89 = AND    \ MOV 0 [SI], BX
  356.                 HERE-T 11 -  @-T $1E8B = AND    \ MOV BX, xxxx
  357.                 HERE-T  7 -  @-T $1E89 = AND    \ MOV yyyy BX
  358.                 OPT_LIMIT HERE-T 15 - U< AND
  359.                 IF      HERE-T 5 - @-T          \ get the address yyyy
  360.                         HERE-T 9 - @-T          \ get the value xxxx
  361.                         -15 ALLOT-T             \ if it matches, discard
  362.                                                 \ previously compiled 14 bytes
  363.                         LIHERE =: LINESTRT
  364.                         [ASSEMBLER]
  365.                         MOV CX, ( xxxx) A;
  366.                         MOV ( yyyy) CX  A;
  367.                         [FORTH]
  368.                 THEN
  369.         THEN
  370.                 [TARGET]
  371.                 ;
  372.  
  373. : IMM/ABS_OPT   ( -- <xxxx> f1 )                \ Immediate optimize
  374.                 A; [FORTH]
  375.                 ?OPT                            \ Are we optimizing?
  376.         IF                                      \ instructions before ?
  377.                 HERE-T  7 -  @-T $4E4E =        \ DEC SI  DEC SI
  378.                 HERE-T  5 -  @-T $1C89 = AND    \ MOV 0 [SI], BX
  379.                 HERE-T  3 - C@-T $BB   = AND    \ MOV BX, # xxxx
  380.                 OPT_LIMIT HERE-T 7 - U<  AND
  381.                 IF      HERE-T 2 - @-T          \ get the address xxxx
  382.                         -7 ALLOT-T              \ if it matches, discard
  383.                                                 \ previously compiled 7 bytes
  384.                         LIHERE =: LINESTRT      \ and return value for BX
  385.                                                 \ on stack with TRUE
  386.                         -1              \ return -1 for immediate
  387.                 ELSE
  388.                         HERE-T  8 -  @-T $4E4E =     \ DEC SI  DEC SI
  389.                         HERE-T  6 -  @-T $1C89 = AND \ MOV 0 [SI], BX
  390.                         HERE-T  4 -  @-T $1E8B = AND \ MOV BX, xxxx
  391.                         IF      HERE-T 2 - @-T       \ get the address xxxx
  392.                                 -8 ALLOT-T           \ if it matches, discard
  393.                                                      \ 8 bytes
  394.                                 LIHERE =: LINESTRT   \ return value for BX
  395.                                 1       \ return 1 for absolute
  396.                         ELSE    0       \ else return 0
  397.                         THEN
  398.                 THEN
  399.         ELSE    0
  400.         THEN
  401.                 [TARGET]
  402.                 ;
  403.  
  404. : IMM_BEFORE    ( -- <xxxx> f1 )                \ Immediate optimize
  405.                 A; [FORTH]
  406.                 ?OPT                            \ Are we optimizing?
  407.         IF                                      \ instructions before ?
  408.                 HERE-T  3 - C@-T $BB   =        \ MOV BX, # xxxx
  409.                 HERE-T  3 - IMM-HERE @ = AND    \ matches our info
  410.                 OPT_LIMIT HERE-T 3 - U<  AND
  411.                 IF      HERE-T 2 - @-T          \ get the address xxxx
  412.                         -3 ALLOT-T              \ if it matches, discard
  413.                                                 \ previously compiled 3 bytes
  414.                         LIHERE =: LINESTRT      \ and return value for BX
  415.                                                 \ on stack with TRUE
  416.                         TRUE
  417.                 ELSE    FALSE
  418.                 THEN
  419.         ELSE    FALSE
  420.         THEN
  421.                 [TARGET]
  422.                 ;
  423.  
  424. >LIBRARY
  425.  
  426. \ ***************************************************************************
  427. \ Optimizer for the @ (fetch) MACRO. Looks for this instruction sequence
  428. \ to preceed it:
  429. \               MOV BX, # xxxx
  430. \
  431. \ When these instructions are found preceeding a store instruction, they
  432. \ are changed to:
  433. \               MOV bx, xxxx
  434. \
  435. \ This provides a savings in both space and time.
  436.  
  437. FORTH   >FORTH
  438.  
  439. : AT_OPT        ( -- )          \ The @ MACRO
  440.                 A; [FORTH]
  441.                 ?OPT            \ Are we optimizing?
  442.         IF                                      \ instructions before ?
  443.                 HERE-T 3 - C@-T $BB   =         \ MOV BX, # xxxx
  444.                 OPT_LIMIT HERE-T 3 - U<  AND
  445.                 IF      HERE-T 2- @-T           \ get the address xxxx
  446.                         -3 ALLOT-T              \ if it matches, discard
  447.                                                 \ previously compiled 3 bytes
  448.                         LIHERE =: LINESTRT
  449.                         [ASSEMBLER]
  450.                         MOV BX, ( xxxx ) A;     \ uses xxxx from above
  451.                         [FORTH]
  452.                 ELSE                            \ cant optimize, so
  453.                         [ASSEMBLER]             \ just compile the
  454.                         MOV BX, 0 [BX] A;
  455.                         [FORTH]
  456.                 THEN
  457.         ELSE    ?REOPT
  458.                 [ASSEMBLER]
  459.                 MOV BX, 0 [BX] A;
  460.                 [FORTH]
  461.         THEN
  462.                 [TARGET]
  463.                 ;
  464.  
  465. : CAT_OPT       ( -- )          \ The @ MACRO
  466.                 A; [FORTH]
  467.                 ?OPT            \ Are we optimizing?
  468.         IF                                      \ instructions before ?
  469.                 HERE-T 3 - C@-T $BB   =         \ MOV BX, # xxxx
  470.                 OPT_LIMIT HERE-T 3 - U<  AND
  471.                 IF      HERE-T 2- @-T           \ get the address xxxx
  472.                         -3 ALLOT-T              \ if it matches, discard
  473.                                                 \ previously compiled 3 bytes
  474.                         LIHERE =: LINESTRT
  475.                         [ASSEMBLER]
  476.                         MOV BL, ( xxxx ) A;     \ uses xxxx from above
  477.                         [FORTH]
  478.                 ELSE                            \ cant optimize, so
  479.                         [ASSEMBLER]             \ just compile the
  480.                         MOV BL, 0 [BX] A;
  481.                         [FORTH]
  482.                 THEN
  483.         ELSE    ?REOPT
  484.                 [ASSEMBLER]
  485.                 MOV BL, 0 [BX] A;
  486.                 [FORTH]
  487.         THEN
  488.                 [TARGET]
  489.                 ;
  490.  
  491. >LIBRARY
  492.  
  493. \ ***************************************************************************
  494. \ MACRO to move BX to the stack
  495. \ ***************************************************************************
  496.  
  497. FORTH   >FORTH
  498.  
  499. : SAVE_BX       ( -- )          \ macro to SAVE BX
  500.                 A; [FORTH]
  501.                 ?OPT            \ Are we optimizing?
  502.         IF                                      \ instructions before ?
  503.                 HERE-T 3 - C@-T $AD   =         \ LODSW
  504.                 HERE-T 2 -  @-T $D88B = AND     \ MOV BX, AX
  505.                 OPT_LIMIT HERE-T 3 - U< AND
  506.                 IF      -3 ALLOT-T              \ if it matches, discard
  507.                                                 \ previously compiled 3 bytes
  508.                         LIHERE =: LINESTRT
  509.                                         \ discards any previously compiled
  510.                                         \ LODSW and MOV BX, AX pair
  511.                                         \ of instructions, since we were
  512.                                         \ about to push BX back on the
  513.                                         \ stack anyway
  514.                         [FORTH]
  515.                 ELSE                            \ Instruction before ?
  516.                         [ASSEMBLER]             \ just compile the
  517.                         DEC SI          A;
  518.                         DEC SI          A;
  519.                         MOV 0 [SI], BX  A;
  520.                         [FORTH]
  521.                 THEN
  522.         ELSE    ?REOPT
  523.                 [ASSEMBLER]
  524.                 DEC SI          A;
  525.                 DEC SI          A;
  526.                 MOV 0 [SI], BX  A;
  527.                 [FORTH]
  528.         THEN
  529.                 [TARGET]
  530.                 ;
  531.  
  532. : LOAD_BX       ( -- )          \ macro to LOAD BX, not an optimizer
  533.                 A;
  534.                 [ASSEMBLER]
  535.                 LODSW           A;
  536.                 MOV BX, AX      A;
  537.                 [TARGET]
  538.                 ;
  539.  
  540. >LIBRARY
  541.  
  542.