annotate python/ppci/buildfunctions.py @ 394:988f3fb861e4

c3 code generator rewrite
author Windel Bouwman
date Thu, 22 May 2014 08:14:12 +0200
parents 6ae782a085e0
children
rev   line source
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
1
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
2 """
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
3 This module contains a set of handy functions to invoke compilation,
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
4 linking
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
5 and assembling.
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
6 """
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
7
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
8 import logging
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
9 from .target import Target
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
10 from .c3 import Builder
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
11 from .irutils import Verifier
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
12 from .codegen import CodeGenerator
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
13 from .transform import CleanPass, RemoveAddZero
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
14 from .linker import Linker
383
173e20a47fda Added linker description loader
Windel Bouwman
parents: 381
diff changeset
15 from .layout import Layout, load_layout
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
16 from .target.target_list import targets
394
988f3fb861e4 c3 code generator rewrite
Windel Bouwman
parents: 393
diff changeset
17 from .outstream import BinaryOutputStream
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
18 from .objectfile import ObjectFile, load_object
393
6ae782a085e0 Added init program
Windel Bouwman
parents: 386
diff changeset
19 from . import DiagnosticsManager
6ae782a085e0 Added init program
Windel Bouwman
parents: 386
diff changeset
20 from .tasks import TaskError, TaskRunner
6ae782a085e0 Added init program
Windel Bouwman
parents: 386
diff changeset
21 from .recipe import RecipeLoader
381
6df89163e114 Fix section and ldr pseudo instruction
Windel Bouwman
parents: 377
diff changeset
22
385
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 383
diff changeset
23
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
24 def fix_target(tg):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
25 """ Try to return an instance of the Target class """
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
26 if isinstance(tg, Target):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
27 return tg
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
28 elif isinstance(tg, str):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
29 if tg in targets:
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
30 return targets[tg]
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
31 raise TaskError('Invalid target {}'.format(tg))
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
32
381
6df89163e114 Fix section and ldr pseudo instruction
Windel Bouwman
parents: 377
diff changeset
33
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
34 def fix_file(f):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
35 """ Determine if argument is a file like object or make it so! """
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
36 if hasattr(f, 'read'):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
37 # Assume this is a file like object
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
38 return f
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
39 elif isinstance(f, str):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
40 return open(f, 'r')
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
41 else:
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
42 raise TaskError('cannot use {} as input'.format(f))
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
43
381
6df89163e114 Fix section and ldr pseudo instruction
Windel Bouwman
parents: 377
diff changeset
44
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
45 def fix_object(o):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
46 if isinstance(o, ObjectFile):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
47 return o
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
48 elif isinstance(o, str):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
49 with open(o, 'r') as f:
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
50 return load_object(f)
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
51 else:
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
52 raise TaskError('Cannot use {} as objectfile'.format(o))
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
53
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
54
383
173e20a47fda Added linker description loader
Windel Bouwman
parents: 381
diff changeset
55 def fix_layout(l):
173e20a47fda Added linker description loader
Windel Bouwman
parents: 381
diff changeset
56 if isinstance(l, Layout):
173e20a47fda Added linker description loader
Windel Bouwman
parents: 381
diff changeset
57 return l
173e20a47fda Added linker description loader
Windel Bouwman
parents: 381
diff changeset
58 elif hasattr(l, 'read'):
173e20a47fda Added linker description loader
Windel Bouwman
parents: 381
diff changeset
59 # Assume file handle
173e20a47fda Added linker description loader
Windel Bouwman
parents: 381
diff changeset
60 return load_layout(l)
173e20a47fda Added linker description loader
Windel Bouwman
parents: 381
diff changeset
61 elif isinstance(l, str):
173e20a47fda Added linker description loader
Windel Bouwman
parents: 381
diff changeset
62 with open(l, 'r') as f:
173e20a47fda Added linker description loader
Windel Bouwman
parents: 381
diff changeset
63 return load_layout(f)
173e20a47fda Added linker description loader
Windel Bouwman
parents: 381
diff changeset
64 else:
173e20a47fda Added linker description loader
Windel Bouwman
parents: 381
diff changeset
65 raise TaskError('Cannot use {} as layout'.format(l))
173e20a47fda Added linker description loader
Windel Bouwman
parents: 381
diff changeset
66
173e20a47fda Added linker description loader
Windel Bouwman
parents: 381
diff changeset
67
393
6ae782a085e0 Added init program
Windel Bouwman
parents: 386
diff changeset
68 def construct(buildfile, targets=[]):
6ae782a085e0 Added init program
Windel Bouwman
parents: 386
diff changeset
69 recipe_loader = RecipeLoader()
6ae782a085e0 Added init program
Windel Bouwman
parents: 386
diff changeset
70 try:
6ae782a085e0 Added init program
Windel Bouwman
parents: 386
diff changeset
71 project = recipe_loader.load_file(buildfile)
6ae782a085e0 Added init program
Windel Bouwman
parents: 386
diff changeset
72 except OSError:
6ae782a085e0 Added init program
Windel Bouwman
parents: 386
diff changeset
73 raise TaskError('Could not construct {}'.format(buildfile))
6ae782a085e0 Added init program
Windel Bouwman
parents: 386
diff changeset
74 project = None
6ae782a085e0 Added init program
Windel Bouwman
parents: 386
diff changeset
75
6ae782a085e0 Added init program
Windel Bouwman
parents: 386
diff changeset
76 if project:
6ae782a085e0 Added init program
Windel Bouwman
parents: 386
diff changeset
77 runner = TaskRunner()
6ae782a085e0 Added init program
Windel Bouwman
parents: 386
diff changeset
78 res = runner.run(project, targets)
6ae782a085e0 Added init program
Windel Bouwman
parents: 386
diff changeset
79 else:
6ae782a085e0 Added init program
Windel Bouwman
parents: 386
diff changeset
80 res = 1
6ae782a085e0 Added init program
Windel Bouwman
parents: 386
diff changeset
81
6ae782a085e0 Added init program
Windel Bouwman
parents: 386
diff changeset
82 return res
6ae782a085e0 Added init program
Windel Bouwman
parents: 386
diff changeset
83
6ae782a085e0 Added init program
Windel Bouwman
parents: 386
diff changeset
84
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
85 def assemble(source, target):
381
6df89163e114 Fix section and ldr pseudo instruction
Windel Bouwman
parents: 377
diff changeset
86 """ Invoke the assembler on the given source, returns an object containing
6df89163e114 Fix section and ldr pseudo instruction
Windel Bouwman
parents: 377
diff changeset
87 the output. """
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
88 logger = logging.getLogger('assemble')
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
89 target = fix_target(target)
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
90 source = fix_file(source)
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
91 output = ObjectFile()
381
6df89163e114 Fix section and ldr pseudo instruction
Windel Bouwman
parents: 377
diff changeset
92 assembler = target.assembler
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
93 logger.debug('Assembling into code section')
394
988f3fb861e4 c3 code generator rewrite
Windel Bouwman
parents: 393
diff changeset
94 ostream = BinaryOutputStream(output)
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
95 ostream.select_section('code')
386
2a970e7270e2 Added repeat assembler macro
Windel Bouwman
parents: 385
diff changeset
96 assembler.prepare()
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
97 assembler.assemble(source, ostream)
381
6df89163e114 Fix section and ldr pseudo instruction
Windel Bouwman
parents: 377
diff changeset
98 assembler.flush()
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
99 return output
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
100
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
101
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
102 def c3compile(sources, includes, target):
381
6df89163e114 Fix section and ldr pseudo instruction
Windel Bouwman
parents: 377
diff changeset
103 """ Compile a set of sources for the given target """
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
104 logger = logging.getLogger('c3c')
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
105 logger.debug('C3 compilation started')
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
106 target = fix_target(target)
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
107 sources = [fix_file(fn) for fn in sources]
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
108 includes = [fix_file(fn) for fn in includes]
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
109 output = ObjectFile()
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
110 diag = DiagnosticsManager()
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
111 c3b = Builder(diag, target)
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
112 cg = CodeGenerator(target)
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
113
394
988f3fb861e4 c3 code generator rewrite
Windel Bouwman
parents: 393
diff changeset
114 output_stream = BinaryOutputStream(output)
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
115
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
116 for ircode in c3b.build(sources, includes):
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
117 if not ircode:
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
118 # Something went wrong, do not continue the code generation
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
119 continue
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
120
393
6ae782a085e0 Added init program
Windel Bouwman
parents: 386
diff changeset
121 d = {'ircode': ircode}
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
122 logger.debug('Verifying code {}'.format(ircode), extra=d)
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
123 Verifier().verify(ircode)
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
124
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
125 # Optimization passes:
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
126 CleanPass().run(ircode)
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
127 Verifier().verify(ircode)
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
128 RemoveAddZero().run(ircode)
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
129 Verifier().verify(ircode)
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
130 CleanPass().run(ircode)
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
131 Verifier().verify(ircode)
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
132
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
133 # Code generation:
393
6ae782a085e0 Added init program
Windel Bouwman
parents: 386
diff changeset
134 d = {'ircode': ircode}
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
135 logger.debug('Starting code generation for {}'.format(ircode), extra=d)
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
136
381
6df89163e114 Fix section and ldr pseudo instruction
Windel Bouwman
parents: 377
diff changeset
137 cg.generate(ircode, output_stream)
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
138
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
139 if not c3b.ok:
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
140 diag.printErrors()
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
141 raise TaskError('Compile errors')
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
142 return output
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
143
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
144
385
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 383
diff changeset
145 def link(objects, layout, target):
381
6df89163e114 Fix section and ldr pseudo instruction
Windel Bouwman
parents: 377
diff changeset
146 """ Links the iterable of objects into one using the given layout """
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
147 objects = list(map(fix_object, objects))
383
173e20a47fda Added linker description loader
Windel Bouwman
parents: 381
diff changeset
148 layout = fix_layout(layout)
385
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 383
diff changeset
149 target = fix_target(target)
d056b552d3f4 Made better use of layout
Windel Bouwman
parents: 383
diff changeset
150 linker = Linker(target)
377
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
151 output_obj = linker.link(objects, layout)
9667d78ba79e Switched to xml for project description
Windel Bouwman
parents:
diff changeset
152 return output_obj