summaryrefslogtreecommitdiff
path: root/iterjit.c
blob: d4d6689d06f31d222e67fe6ee449724cf042b8c0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
/*
  
  Iterator based JIT compiler

  There is a new structure that can be either source or
  destination. It contains function pointers that know how to generate
  pixels. The function pointers:

  Source iterators:

  - begin():		generates code that runs before the kernel
  - begin_line():	generates code that runs before each scanline
  - get_one_pixel():	   generates code that reads one pixel
  - get_two_pixels():	   --- two pixels
  - get_four_pixels():	   --- four pixels
  - get_eight_pixels():	   --- eight pixels
  - get_sixteen_pixels():  ---
  - end_line();
  - end();

  An iterator is associated with a format:

  format_4_a8r8g8b8
  format_16_a8
  format_8_a8r8g8b8
  and possibly others

  The iterator is supposed to return pixels in that format. It will
  never be asked to fetch more pixels than the format supports. Ie.,
  get_sixteen_pixels() will never be called if the format is
  format_4_a8r8g8b8().

  All the get_n_pixels() return a register where they left the pixel.

  There are also combiners. These are also associated with a format
  and know how to combine pixels in that format with each other.

  Destination iterators are responsible for driving a lot of the access?

  They have a method: process_scanline (src_iter, mask_iter, combiner)
  which is responsible for:

  - generating the inner loop,
  - calling src iter,
  - callling mask iter,
  - calling combiner
  - writing back

  They are specific to a format, and an intermediate format.

  There may also be setup()/setup_line() methods required.

  Flow:
  - outer loop:
	- generates outer loop
	- src/mask/dest have pre-scanline setups called
	- body is generated by destination iter
	- src/mask/dest have post-scanline finalizers called

  - destination iter:
	- for each alignment loop, it generates an inner loop
	- body of inner loop is generated by combiner
	- combiner returns pixels or an indication that 
	     no change is required
	- destination iter writes back if necessary
	- advances pointer

  - combiner drives generation of pixels
  - if there is a mask, then
	- tell mask iter to load n pixels
	- generate code to check if all pixels are 0
	- if it is, then
		- depending on operator
			- return 0
			- return "no change needed"
	  else:
		- tell source iter to load n pixels
		- add code to multiply them together
		- depending on operator
			- add code to check if a result is 0xff
			- if it is, then
				- return source
			  else:
				- tell destination to read a pixel
				- generate code to combine with source
				- return result
	  tell mask iter to advance
    else:
          - tell source iter to load n pixels
	  - depending on operator 
		- add code to check if source is 0xff
		- if it is, then
			- return source
		  else:
			- tell destination to read pixel
			- generate code to combine with source
			- return result
    tell source iter to advance
*/

#include <stdio.h>
#include "simplex86.h"
#include "simple-reg.h"
#include "stack-man.h"
#include "crc32.h"

typedef struct jit_dest_iter_t jit_dest_iter_t;
typedef struct jit_src_iter_t jit_src_iter_t;
typedef struct jit_combiner_t jit_combiner_t;
typedef struct jit_t jit_t;

struct jit_t
{
    assembler_t *assembler;
    fragment_t *fragment;
    stack_man_t stack_man;
    reg_alloc_t reg_alloc;
};

struct jit_src_iter_t
{
    void (* begin) (jit_src_iter_t *src, jit_t *jit);
    void (* begin_line) (jit_src_iter_t *src, jit_t *jit);
    op_t (* load_pixels) (jit_src_iter_t *src, jit_t *jit, int n_pixels);
    void (* advance_pixels) (jit_src_iter_t *src, jit_t *jit, int n_pixels);
    void (* end_line) (jit_src_iter_t *src, jit_t *jit);
    void (* end) (jit_src_iter_t *src, jit_t *jit);
};

struct jit_combiner_t
{
    op_t (* combine) (jit_combiner_t *combiner, jit_t *jit,
		      jit_src_iter_t *src,
		      jit_src_iter_t *mask,
		      jit_dest_iter_t *dest);
};

struct jit_dest_iter_t
{
    void (* begin) (jit_dest_iter_t *dest, jit_t *jit);
    op_t (* load_pixels) (jit_dest_iter_t *dest, jit_t *jit, int n_pixels);
    void (* advance_pixels) (jit_dest_iter_t *dest, jit_t *jit, int n_pixels);
    void (* process_line) (jit_dest_iter_t *dest_iter,
			   jit_t *jit,
			   jit_src_iter_t *src_iter,
			   jit_src_iter_t *mask_iter,
			   jit_combiner_t *combiner);
    void (* end) (jit_dest_iter_t *dest, jit_t *jit);
};

static void
dest_a8r8g8b8_begin (jit_dest_iter_t *	dest,
		     jit_t *		jit)
{
    BEGIN_ASM (jit->fragment)
    END_ASM ();
}

static void
dest_a8r8g8b8_process_line (jit_dest_iter_t *dest,
			    jit_t *jit,
			    jit_src_iter_t *src,
			    jit_src_iter_t *mask,
			    jit_combiner_t *combiner)
{
    src->begin_line (src, jit);

    BEGIN_ASM (jit->fragment)
	
	
    END_ASM ();
}

static void
dest_a8r8g8b8_end (jit_dest_iter_t *dest, jit_t *jit)
{
    
}

jit_dest_iter_t *
dest_iter_create_a8r8g8b8 (jit_dest_iter_t *dest)
{
    jit_dest_iter_t *iter = malloc (sizeof *iter); /* FIXME OOM */

    iter->begin = dest_a8r8g8b8_begin;
    iter->process_line = dest_a8r8g8b8_process_line;
    iter->end = dest_a8r8g8b8_end;

    return iter;
}

void
generate_kernel (jit_t *jit,
		 jit_src_iter_t *src_iter,
		 jit_src_iter_t *mask_iter,
		 jit_dest_iter_t *dest_iter,
		 jit_combiner_t *combiner)
{
    reg_context_t context;
    op_t h = reg_context_alloc (&context, jit->fragment);

    src_iter->begin (src_iter, jit);
    if (mask_iter)
	mask_iter->begin (mask_iter, jit);
    dest_iter->begin (dest_iter, jit);

    BEGIN_ASM (jit->fragment)
	I_test, h, h,
	I_jz, LABEL ("done"),
	DEFINE_LABEL ("outer_loop"),
    END_ASM ();

    dest_iter->process_line (dest_iter, jit, 
			     src_iter, mask_iter, combiner);
    
    BEGIN_ASM (jit->fragment)
	I_sub, h, IMM (1),
	I_jnz, LABEL ("outer_loop"),
	DEFINE_LABEL ("done"),
    END_ASM ();
    
    dest_iter->end (dest_iter, jit);
    if (mask_iter)
	mask_iter->end (mask_iter, jit);
    src_iter->end (src_iter, jit);
}

int
main ()
{
    /* n_8_8888() */
    printf ("iter jit\n");

    return 0;
}