source: proto/s2k/trunk/framework/src/toolchain/s2k/transformer/visitors/S2K2B2K/S2K2B2KTransformer.java @ 3774

Last change on this file since 3774 was 3774, checked in by ksherdy, 4 years ago

Updated toolchain for filter definitions.

File size: 32.3 KB
Line 
1/*
2 * Transforms s2k ASTs (non-final, and final-block translation)
3 * to b2k AST (kernels).
4 *
5 * @author Ken Herdy <ksherdy at sfu dot ca>
6 */
7
8package toolchain.s2k.transformer.visitors.S2K2B2K;
9
10
11import java.lang.reflect.Constructor;
12import java.util.*;
13
14// b2k imports
15import b2k.ast.*;
16import b2k.inputHandler.*;
17import b2k.tokens.Token;
18
19import toolchain.b2k.ast.Accessors;
20import toolchain.b2k.ast.Generators;
21import toolchain.b2k.ast.Mutators;
22import toolchain.b2k.lang.KernelState;
23import toolchain.b2k.lang.B2KBuiltin;
24import static toolchain.b2k.lang.B2KBuiltin.DO_BLOCK;
25import static toolchain.b2k.lang.B2KBuiltin.DO_FINAL_BLOCK;
26import static toolchain.b2k.lang.B2KBuiltin.CLEAR;
27import static toolchain.b2k.lang.idisa.IDISABuiltin.*;
28import static toolchain.b2k.lang.types.PrimitiveType.BITBLOCK_SIZE;
29
30// non-conflicting imports
31import toolchain.s2k.lang.BuiltinCallUtil;
32import toolchain.s2k.lang.S2KBuiltin;
33import toolchain.s2k.lang.BuiltinEncoder;
34import toolchain.s2k.lang.carrySet.CarrySetEncoder;
35import toolchain.s2k.lang.S2KBuiltinTranslator;
36import toolchain.s2k.transformer.visitors.infoSet.PropertyInfoSet;
37import toolchain.s2k.transformer.visitors.infoSet.PropertyInfoSetMapBuilder;
38
39
40public class S2K2B2KTransformer {
41
42    public static ASTNode apply(BuiltinEncoder builtinEncoder, CarrySetEncoder carrySetEncoder, s2k.ast.ASTNode s2kASTree, s2k.ast.ASTNode s2kFinalBlockASTree) {
43
44        // S2B
45        Map<s2k.ast.ASTNode, PropertyInfoSet> propInfoSetMap            = PropertyInfoSetMapBuilder.forTree(s2kASTree);
46        Context context                                                 = new Context(builtinEncoder, carrySetEncoder, true, false, 0);
47        S2K2B2KTranslator S2BXTranslator                                = new S2K2B2KTranslator(propInfoSetMap, context);
48        ASTNode b2kASTree                                                   = s2kASTree.accept(S2BXTranslator);                   
49
50        // S2B final block mode
51        Map<s2k.ast.ASTNode, PropertyInfoSet> finalBlockPropInfoSetMap  = PropertyInfoSetMapBuilder.forTree(s2kFinalBlockASTree);
52        Context finalBlockContext                                       = new Context(builtinEncoder, carrySetEncoder, true, true, 0);
53        S2K2B2KTranslator finalBlockS2BTranslator                       = new S2K2B2KTranslator(finalBlockPropInfoSetMap, finalBlockContext);
54        ASTNode b2kFinalBlockASTree                                     = s2kFinalBlockASTree.accept(finalBlockS2BTranslator);
55       
56        List<s2k.ast.FuncDefNode> funcDefs = toolchain.s2k.ast.Accessors.funcDefs((s2k.ast.ProgramNode) s2kASTree);
57       
58        for(s2k.ast.FuncDefNode funcDef : funcDefs) {
59           
60            String kernelName           = toolchain.s2k.ast.Accessors.name(funcDef);
61            Locator locator             = Generators.makeTextLocation(funcDef.getLocation());
62            PropertyInfoSet propInfoSet = propInfoSetMap.get(funcDef);
63           
64            List<FuncCallNode> carryInitFuncCalls       = makeCarryInitFuncCallNodes(locator, context, propInfoSet);
65            InitDefNode initDef                                 = makeInitDefNode(locator, propInfoSet);
66            addCarryInitFuncCallNodes(carryInitFuncCalls, initDef);
67           
68            FuncDefNode doBlockFuncDef      = Accessors.funcDefForName(b2kASTree, kernelName);
69            FuncDefNode doFinalBlockFuncDef = Accessors.funcDefForName(b2kFinalBlockASTree, kernelName);
70           
71            Mutators.rename(doBlockFuncDef, DO_BLOCK.b2kName());         
72            Mutators.rename(doFinalBlockFuncDef, DO_FINAL_BLOCK.b2kName());
73           
74            FuncDefNode clearFuncDef            = makeClearFuncDefNode(locator, CLEAR.b2kName());
75            addCarryInitFuncCallNodes(carryInitFuncCalls, clearFuncDef);
76                       
77            KernelDefNode kernelDef             = Generators.makeKernelDef(locator,
78                                                                            kernelName,
79                                                                            initDef, 
80                                                                            doBlockFuncDef, 
81                                                                            doFinalBlockFuncDef,
82                                                                            clearFuncDef);
83           
84            addCarryDeclareFuncCall(locator, context, propInfoSet, kernelDef);
85            doBlockFuncDef.updateSelf(kernelDef);
86        }
87
88        return b2kASTree;
89    }
90
91    private static List<FuncCallNode> makeCarryInitFuncCallNodes(Locator locator, Context context,
92            PropertyInfoSet propInfoSet) {
93       
94        List<FuncCallNode> funcCallNodes = new ArrayList<FuncCallNode>();
95       
96        Integer [] values = arrayFromList(propInfoSet.carry1InitialValues);
97        for(int i = 0; i < values.length; i++) {   
98            if(values[i] > 0) {
99                FuncCallNode setCarryFuncCall = Generators.makeCarryFlipCall(locator, context, i);
100                funcCallNodes.add(setCarryFuncCall);
101                //kernelDef.appendChild(setCarryFuncCall);
102            }
103        }
104       
105        return funcCallNodes;
106    }
107
108    private static void addCarryInitFuncCallNodes(List<FuncCallNode> carryInitFuncCallNodes, FuncDefNode funcDef) {
109        for(FuncCallNode funcCall : carryInitFuncCallNodes) {
110                Accessors.body(funcDef).appendChild(funcCall);
111        }
112    }
113   
114    private static void addCarryInitFuncCallNodes(List<FuncCallNode> carryInitFuncCallNodes, InitDefNode kernelDef) {
115        for(FuncCallNode funcCall : carryInitFuncCallNodes) {
116                kernelDef.appendChild(funcCall);
117        }
118    }
119   
120    private static void addCarryDeclareFuncCall(Locator locator,
121            Context context, PropertyInfoSet propInfoSet,
122            KernelDefNode initDef) {
123       
124        FuncCallNode carryDeclareCall = Generators.makeCarryDeclareCall(locator, 
125                context, 
126                propInfoSet.carry1Count,
127                propInfoSet.carryNCount);
128        initDef.appendChild(carryDeclareCall);
129    }
130
131    private static InitDefNode makeInitDefNode(Locator locator,
132            PropertyInfoSet propInfoSet) {
133       
134        InitDefNode initDef = Generators.makeInitDefNode(locator);         
135       
136        // kernel properties
137        IdentifierNode propertyName         = Generators.makeIdentifierNode(locator, KernelState.CARRY1_INITIAL_VALUES.name());
138        PropertyValueNode propertyValue     = Generators.makePropertyValueNode(locator, arrayFromList(propInfoSet.carry1InitialValues));
139        KernelPropertyNode property         = Generators.makeKernelPropertyNode(propertyName, propertyValue);
140        initDef.appendChild(property);
141
142        propertyName        = Generators.makeIdentifierNode(locator, KernelState.CARRY1_COUNT.name());
143        propertyValue       = Generators.makePropertyValueNode(locator, propInfoSet.carry1Count);
144        property            = Generators.makeKernelPropertyNode(propertyName, propertyValue);
145        initDef.appendChild(property);
146
147        ////////////////////////////////////////////////////////////
148        // CarryN
149        // propertyName       = Generators.makeIdentifierNode(locator, KernelState.CARRYN_INITIAL_VALUES.name());
150        // propertyValue      = Generators.makePropertyValueNode(locator, propInfoSet.getCarryNInitValues());
151        // property           = Generators.makeKernelPropertyNode(propertyName, propertyValue);
152        // stateDefNode.appendChild(property);
153
154        propertyName       = Generators.makeIdentifierNode(locator, KernelState.CARRYN_COUNT.name());
155        propertyValue      = Generators.makePropertyValueNode(locator, propInfoSet.carryNCount);
156        property           = Generators.makeKernelPropertyNode(propertyName, propertyValue);
157        initDef.appendChild(property);
158
159        propertyName       = Generators.makeIdentifierNode(locator, KernelState.LOOK_AHEAD.name());
160        propertyValue      = Generators.makePropertyValueNode(locator, propInfoSet.lookAhead);
161        property           = Generators.makeKernelPropertyNode(propertyName, propertyValue);
162        initDef.appendChild(property);
163
164        propertyName       = Generators.makeIdentifierNode(locator, KernelState.LOOK_BEHIND.name());
165        propertyValue      = Generators.makePropertyValueNode(locator, propInfoSet.lookBehind);
166        property           = Generators.makeKernelPropertyNode(propertyName, propertyValue);
167        initDef.appendChild(property);
168       
169        return initDef;
170    }
171   
172    private static FuncDefNode makeClearFuncDefNode(Locator locator, String funcName) {
173        FuncDefNode funcDef = Generators.makeFuncDefNode(locator, funcName);
174        return funcDef;
175    }
176   
177    private static Integer[] arrayFromList(List<Integer> list) {
178        return list.toArray(new Integer [list.size()]);
179    }
180   
181    private static class S2K2B2KTranslator extends s2k.ast.ASTVisitor.Default<ASTNode> {
182
183        private Map<s2k.ast.ASTNode, PropertyInfoSet> propInfoSetMap;
184        private Context context;
185
186        S2K2B2KTranslator(Map<s2k.ast.ASTNode, PropertyInfoSet> propInfoSetMap, Context context) {
187            this.propInfoSetMap = propInfoSetMap;
188            this.context = context;
189        }
190
191        // General case.
192        @Override
193        public ASTNode defaultVisitLeave(s2k.ast.ASTNode node, List<ASTNode> childResults) {
194            Class<?> nodeClass = node.getClass();
195            String nodeName = nodeClass.getSimpleName();
196            String b2kNodeName = "b2k.ast." + nodeName;
197
198            b2k.tokens.Token token = Generators.makeToken(node.getToken());
199            try {
200                Class<?> b2kNodeClass = Class.forName(b2kNodeName);
201                Constructor<?> constructor = b2kNodeClass.getConstructor(b2k.tokens.Token.class);
202                ASTNode b2kNode = (ASTNode) constructor.newInstance(token);
203                appendChildResults(b2kNode, childResults);
204                return b2kNode;
205            } catch (Exception e) {
206                e.printStackTrace();
207            }
208            return null;
209        }
210
211        protected static void appendChildResults(ASTNode snode, List<ASTNode> childResults) {
212            for(ASTNode child : childResults) {
213                snode.appendChild(child);
214            }
215        }
216
217        ////////////////////////////////////////////////////////////////////////////////////
218        // s2k to b2k translation (special cases)
219        ////////////////////////////////////////////////////////////////////////////////////
220       
221        ////////////////////////////////////////////////////////////////////////////////////
222        // FilterDef
223        //
224        public ASTNode visitLeave(s2k.ast.ParameterListNode snode, List<ASTNode> childResults) {
225                ASTNode replacement = Generators.makeParameterListNode(Generators.makeToken(snode.getToken()));
226                appendChildResults(replacement, childResults);
227                return replacement;             
228        }
229       
230        ////////////////////////////////////////////////////////////////////////////////////
231        // FilterParameterModeNode
232        public ASTNode visitLeave(s2k.ast.FilterParameterModeNode snode, List<ASTNode> childResults) {
233                ASTNode replacement = Generators.makeParameterModeNode(Generators.makeToken(snode.getToken()));
234                return replacement;             
235        }
236
237       
238        public ASTNode visitLeave(s2k.ast.FilterParameterNode snode, List<ASTNode> childResults) {
239                ASTNode replacement = Generators.makeParameterNode(Generators.makeToken(snode.getToken()));
240                appendChildResults(replacement, childResults);
241                return replacement;
242        }       
243       
244        public ASTNode visitLeave(s2k.ast.FuncDefNode snode, List<ASTNode> childResults) {
245           
246            ASTNode replacement = defaultVisitLeave(snode, childResults);
247
248            int carry1Count = propInfoSetMap.get(snode).carry1Count;
249
250            if(needsCarryAdjustment(context, carry1Count) ) { 
251                addCarryAdjustment((FuncDefNode) replacement, context, carry1Count);
252            }
253                       
254            if(context.isFinalBlockMode()) {
255                if(!hasEOFMaskParameter((FuncDefNode)replacement)) {
256                    b2k.ast.ParameterNode EOFMaskParameter = Generators.makeEofMaskParameter(replacement);
257                    Generators.appendParameter((FuncDefNode) replacement, EOFMaskParameter);
258                }
259            }
260                       
261            return replacement;
262         }
263       
264        private boolean needsCarryAdjustment(Context context, int carry1Count) {
265            return !context.isFinalBlockMode() && carry1Count > 0;
266        }
267
268        private void addCarryAdjustment(FuncDefNode node, Context context, int carry1Count) {
269            FuncCallNode carryAdjustment = Generators.makeCarryAdjustmentCall(node, context, carry1Count);
270            ASTNode body = Accessors.body(node);
271            body.appendChild(carryAdjustment);
272        }       
273       
274        private boolean hasEOFMaskParameter(FuncDefNode node) {
275            if(Accessors.hasParameters(node)) {
276                ParameterListNode parameterList = Accessors.parameterListNode(node);
277                ASTNode lastParameter = parameterList.lastChild();
278
279                final String EOF_Mask = B2KBuiltin.EOF_MASK.b2kName(); //context.getBuiltinEncoder().getName(S2KBuiltin.EOF_MASK);
280
281                if(Accessors.name(lastParameter).equals(EOF_Mask)) {
282                    return true;
283                } 
284            }
285            return false;
286        }
287       
288        ////////////////////////////////////////////////////////////////////////////////////
289        // IfStmt       
290        //
291        //  'carry-in' - enabled
292        //
293        //  if (condition) { S* } => if (Any(Or(condition, CarryTest(carry1Position, carry1Count))) { S* }
294        //       
295        //  'carry-in' - disabled
296        //       
297        //  if (condition) { S* } => if (Any(condition)) { S* }
298        //
299        //  Note: ANDC EOF_Mask is not applied to 'condition' because we test the position following the EOF for errors.
300        //
301        public ASTNode visitLeave(s2k.ast.IfStmtNode snode, List<ASTNode> childResults) {
302           
303            int carryNCount = propInfoSetMap.get(snode).carryNCount;
304            assert (carryNCount == 0): "Advance(x,n) illegal within an if statement \n";    // should be better diagnostic
305
306            IfStmtNode replacement = (IfStmtNode) defaultVisitLeave(snode, childResults);
307
308            int carry1Count     = propInfoSetMap.get(snode).carry1Count;
309
310            if(ifNeedsCarryProcessing(context, carry1Count)) {
311
312                int carry1Position  = propInfoSetMap.get(snode).carry1Position;
313                orCarryRangeIntoCondition(replacement, context, carry1Position, carry1Count);
314                appendCarryDequeueEnqueueToElseClause(replacement, context, carry1Position, carry1Count);
315            }
316
317            Mutators.surroundConditionWithBitBlockAny(replacement, Accessors.condition(replacement));
318
319            return replacement;
320        }
321
322        private boolean ifNeedsCarryProcessing(Context context, int carry1Count) {
323            return context.isCarryInMode() && carry1Count > 0;
324        }
325                 
326        private void orCarryRangeIntoCondition(IfStmtNode node, Context context, int carry1Position, int carry1Count) {
327            ASTNode condition = Accessors.condition(node);
328            ASTNode replacementCondition = Generators.makeBitwiseOrCarryTest(condition.deepCopy(), context, carry1Position, carry1Count);
329           
330            node.replaceChild(condition, replacementCondition);
331        }
332
333        private void appendCarryDequeueEnqueueToElseClause(IfStmtNode node, Context context, int carry1Position, int carry1Count) {
334            Locator locator = node.getLocation();
335            ASTNode carryDequeueEnqueue = Generators.makeCarryDequeueEnqueueCall(locator, context, carry1Position, carry1Count);
336
337            ensureHasElseClause(node); 
338            Accessors.elseClause(node).appendChild(carryDequeueEnqueue);
339        }       
340       
341        private void ensureHasElseClause(IfStmtNode node) {
342            if (!Accessors.hasElseClause(node)) {   
343                BlockStmtNode blockStmtNode = Generators.makeBlockStmtNode(node);
344                node.appendChild(blockStmtNode); 
345            }
346        }
347
348        ////////////////////////////////////////////////////////////////////////////////////
349        // WhileStmt translation       
350        //
351        //   if 'carry1Count' is zero
352        //
353        //     while(condition) body => while(condition) body
354        //
355        //   else if 'carry1Count' greater than zero
356        //
357        //     if 'carry-in' mode is disabled
358        //
359        //       while(condition) body =>
360        //
361        //       while(bitblock::any(condition')) {
362        //           carryDeclare(localCarrySetID, carry1Count, carryNCount)
363        //           phi(body)           
364        //           carryCombine(carrySetID, localCarrySetID, carry1Position, carry1Count)
365        //       }
366        //
367        //     else if 'carry-in' mode is enabled
368        //
369        //       while(condition) body  =>
370        //
371        //       if(bitblock::any(condition''))) {
372        //         body
373        //         while(bitblock::any(condition')) {
374        //           carryDeclare(localCarrySetID, carry1Count, carryNCount)
375        //           phi(body)           
376        //           carryCombine(carrySetID, localCarrySetID, carry1Position, carry1Count)
377        //         }
378        //       }
379        //       else {
380        //         carryDequeEnque(carryBase, carry1Count)
381        //       }
382        //
383        //   condition'      = condition ANDC EOFMask if in finalBlock mode, bitblock::Any
384        //   condition''     = condition OR carryTest in carryIn mode, ANDC EOFMask if in finalBlock mode, bitblock::Any
385        //   phi is recursive transform with depth+1 and carryIn=false, using localCarrySet       
386        //
387        //
388        public ASTNode visitLeave(s2k.ast.WhileStmtNode snode, List<ASTNode> childResults) {
389
390            int carryNCount = propInfoSetMap.get(snode).carryNCount;
391            assert (carryNCount == 0): "Advance(x,n) illegal within an if statement \n";    // should be better diagnostic           
392           
393            ASTNode replacement         = defaultVisitLeave(snode, childResults);
394           
395            int carry1Count = propInfoSetMap.get(snode).carry1Count;
396            if(ifNeedsCarryProcessing(context, carry1Count)) {
397
398                    ASTNode outerCondition      = Accessors.condition((WhileStmtNode) replacement);
399                    ASTNode outerBody           = Accessors.body((WhileStmtNode) replacement);
400                    replacement = makeGeneralWhileReplacement(snode, outerCondition, outerBody);
401
402                    if(context.isFinalBlockMode()) {
403                        andConditionWithEOFMask(Accessors.condition((IfStmtNode) replacement));                   
404                    }
405                   
406                    Mutators.surroundConditionWithBitBlockAny(replacement, Accessors.condition((IfStmtNode) replacement));
407                   
408            } else {
409               
410                if(context.isFinalBlockMode()) {
411                    andConditionWithEOFMask(Accessors.condition((WhileStmtNode) replacement));                   
412                }
413               
414                Mutators.surroundConditionWithBitBlockAny(replacement, Accessors.condition((WhileStmtNode) replacement));   
415            }
416           
417            return replacement;
418        }       
419       
420        private IfStmtNode makeGeneralWhileReplacement(s2k.ast.WhileStmtNode snode, ASTNode condition, ASTNode body) {
421            Locator locator = Generators.makeTextLocation(snode.getLocation());
422
423            int carry1Position  = propInfoSetMap.get(snode).carry1Position;
424            int carry1Count     = propInfoSetMap.get(snode).carry1Count;
425
426            ASTNode outerCondition      = makeOuterIfCondition(condition, carry1Position, carry1Count);   
427            BlockStmtNode thenClause    = outerIfThenClause(snode, condition, body, carry1Position, carry1Count);
428            BlockStmtNode elseClause    = outerIfElseClause(snode, carry1Position, carry1Count);
429
430            return Generators.makeIfStmtNode(locator, outerCondition, thenClause, elseClause);
431        }       
432       
433        private ASTNode makeOuterIfCondition(ASTNode condition, int carry1Position, int carry1Count) {
434            ASTNode result = condition.deepCopy();
435            if(carry1Count > 0) {
436                result = Generators.makeBitwiseOrCarryTest(result, context, carry1Position, carry1Count);
437            }
438            return result;
439        }         
440       
441        private void andConditionWithEOFMask(ASTNode condition) {
442            Locator locator = condition.getLocation();
443            ASTNode replacement = Generators.makeExprAndEofMaskCall(locator, condition.deepCopy());
444            condition.updateSelf(replacement);
445        }
446       
447        private BlockStmtNode outerIfThenClause(s2k.ast.WhileStmtNode snode, ASTNode condition, ASTNode body, int carry1Position, int carry1Count) {
448            Locator locator                     = Generators.makeTextLocation(snode.getLocation());
449
450            BlockStmtNode outerIfThenBlockStmt  = Generators.makeBlockStmtNode(locator, body);
451            WhileStmtNode innerWhile            = makeInnerWhile(snode, condition, carry1Position, carry1Count); 
452            outerIfThenBlockStmt.appendChild(innerWhile);
453
454            return outerIfThenBlockStmt;
455        }       
456       
457        private WhileStmtNode makeInnerWhile(s2k.ast.WhileStmtNode snode, ASTNode condition, int carry1Position, int carry1Count) {
458
459            Locator locator = Generators.makeTextLocation(snode.getLocation());
460
461            Context localContext = context.incrementDepth().clearCarryIn();             
462            s2k.ast.BlockStmtNode sbody = toolchain.s2k.ast.Accessors.body(snode);
463            BlockStmtNode body = transformBody(sbody, localContext);
464
465            WhileStmtNode innerWhile = new WhileStmtNode(Generators.makeToken(snode.getToken()));
466           
467            innerWhile.appendChild(condition);
468           
469            if(context.isFinalBlockMode()) {
470                andConditionWithEOFMask(Accessors.condition((WhileStmtNode) innerWhile));                   
471            }
472           
473            Mutators.surroundConditionWithBitBlockAny(innerWhile, Accessors.condition((WhileStmtNode) innerWhile));
474           
475            innerWhile.appendChild(body);
476           
477            insertCarryDeclare(locator, body, localContext, carry1Count, 0); // carryNCount == 0 by assertion in visitLeave(WhileStmtNode)
478            appendCarryCombine(locator, body, context, localContext, carry1Position, carry1Count);
479
480            return innerWhile;
481        }       
482       
483        private BlockStmtNode transformBody(s2k.ast.ASTNode snode, Context localContext) {
484
485            Map<s2k.ast.ASTNode, PropertyInfoSet> propInfoSetMap  = PropertyInfoSetMapBuilder.forTree(snode);
486            S2K2B2KTranslator S2BXTranslator                      = new S2K2B2KTranslator(propInfoSetMap, localContext);
487            BlockStmtNode body                                    = (BlockStmtNode) snode.accept(S2BXTranslator); 
488            return body;
489        }       
490       
491        private BlockStmtNode outerIfElseClause(s2k.ast.WhileStmtNode snode, int carry1Position, int carry1Count) {
492           
493            Locator locator                     = Generators.makeTextLocation(snode.getLocation());
494            FuncCallNode carryDequeueEnqueue    = Generators.makeCarryDequeueEnqueueCall(locator, context, carry1Position, carry1Count);
495            return Generators.makeBlockStmtNode(locator, carryDequeueEnqueue);
496        }       
497       
498        private void insertCarryDeclare(Locator locator, ASTNode body, Context localContext, int carry1Count, int carryNCount) {
499
500            FuncCallNode carryDeclare = Generators.makeCarryDeclareCall(locator, localContext, carry1Count, carryNCount);
501            body.insertChild(carryDeclare);
502        }
503       
504        private void appendCarryCombine(Locator locator, ASTNode body, Context context, Context localContext, int carry1Position, int carry1Count) {
505                       
506            FuncCallNode localCarryCombine = Generators.makeLocalCarryCombineCall(locator, context, localContext, carry1Position, carry1Count); 
507            body.appendChild(localCarryCombine);
508        }       
509       
510        ////////////////////////////////////////////////////////////////////////////////////
511        // FuncCall       
512        //
513        // Translation of s2k builtin depends on 'carry-in' mode, 'final-block' mode, and
514        // the prior execution of the TempifyCarryBuiltinCalls transformer.
515        //
516        public ASTNode visitLeave(s2k.ast.FuncCallNode snode, List<ASTNode> childResults) {
517
518            ASTNode replacement = null;
519           
520            if (BuiltinCallUtil.isCarryNone(snode)) { 
521
522                S2KBuiltin builtin = BuiltinCallUtil.builtin(snode);
523                S2KBuiltinTranslator translator = builtin.getTranslator();
524
525                ASTNode funcCallArgsList = childResults.get(1);
526                List<ASTNode> args = funcCallArgsList.getChildren();
527                replacement = translator.translate(builtin, snode, context, args); 
528               
529            } else {
530
531                replacement  = new FuncCallNode(Generators.makeToken(snode.getToken()));
532                appendChildResults(replacement, childResults);
533            }
534           
535            return replacement;
536        }
537
538        ////////////////////////////////////////////////////////////////////////////////////
539        // AssignNode       
540        public ASTNode visitLeave(s2k.ast.AssignNode snode, List<ASTNode> childResults) {
541
542            s2k.ast.ASTNode rhs = toolchain.s2k.ast.Accessors.rhs(snode);
543
544            if(BuiltinCallUtil.isCarry(rhs)) {
545
546                Locator locator = Generators.makeTextLocation(snode.getLocation());
547
548                ASTNode funcCallArgsList = childResults.get(1).child(1);
549                List<ASTNode> args = funcCallArgsList.getChildren();
550
551                ASTNode carryCall = makeCarryCall(locator, context, rhs);
552                args.add(carryCall);
553
554                ASTNode returnValue = childResults.get(0);
555                args.add(returnValue);
556
557                S2KBuiltin builtin = BuiltinCallUtil.builtin(rhs);
558                S2KBuiltinTranslator translator = builtin.getTranslator();
559                ASTNode b2kBlkFuncCall = translator.translate(builtin, (s2k.ast.FuncCallNode) rhs, context, args);
560               
561                return Generators.makeAssignNode(locator, carryCall, b2kBlkFuncCall);
562
563            } 
564
565            ASTNode replacement  = new AssignNode(Generators.makeToken(snode.getToken()));
566            appendChildResults(replacement, childResults);
567            return replacement;
568        }
569       
570        private ASTNode makeCarryCall(Locator locator, Context context, s2k.ast.ASTNode rhs) {
571            ASTNode carryCall = null;
572           
573            if(BuiltinCallUtil.isCarry1(rhs)) {
574                int carry1Position = propInfoSetMap.get(rhs).carry1Position;
575                carryCall = Generators.makeGetCarryCall(locator, context, carry1Position);
576
577            } else if(BuiltinCallUtil.isCarryN(rhs)) {
578                int carryNPosition = propInfoSetMap.get(rhs).carryNPosition;
579                carryCall = Generators.makePending64Call(locator, context, carryNPosition);
580            }
581           
582            return carryCall;
583        }           
584       
585        ////////////////////////////////////////////////////////////////////////////////////
586        // StreamType // TODO - KH: Handle field width attributes on s2k stream types
587        public ASTNode visitLeave(s2k.ast.StreamTypeNode snode, List<ASTNode> childResults) {
588
589            String lexeme = b2k.lexicalAnalyzer.Lextant.BITBLOCK.getPrimaryLexeme();
590
591            Token token = b2k.tokens.LextantToken.make(Generators.makeTextLocation(snode.getToken().getLocation()), 
592                    lexeme, 
593                    b2k.lexicalAnalyzer.Lextant.forLexeme(lexeme, Generators.LEXICAL_CONTEXT)); 
594
595            ASTNode replacement = new BitBlockTypeNode(token);
596            appendChildResults(replacement, childResults);
597           
598            return replacement;
599        }
600
601        public ASTNode visitLeave(s2k.ast.IntegerConstantNode snode, List<ASTNode> childResults) {
602            ASTNode replacement = new IntegerConstantNode(Generators.makeToken(snode.getToken()));
603            int value = new Integer(replacement.getToken().getLexeme());
604            ((IntegerConstantNode)replacement).setValue(value); 
605            appendChildResults(replacement, childResults);
606            return replacement;
607        }
608
609        ////////////////////////////////////////////////////////////////////////////////////
610        // Bitwise / BinaryOp
611        public ASTNode visitLeave(s2k.ast.BinaryOperatorNode snode, List<ASTNode> childResults) {
612
613            s2k.tokens.Token tokenS = snode.getToken();
614            s2k.ast.ASTNode lhsS = toolchain.s2k.ast.Accessors.lhs(snode);
615            s2k.ast.ASTNode rhsS = toolchain.s2k.ast.Accessors.rhs(snode);
616
617            ASTNode replacement = null;
618 
619            if(tokenS.isLextant(s2k.lexicalAnalyzer.Lextant.AND, s2k.lexicalAnalyzer.Lextant.OR, s2k.lexicalAnalyzer.Lextant.XOR)) {
620
621                TextLocation locator = Generators.makeTextLocation(tokenS.getLocation());
622                ASTNode lhs = childResults.get(0);
623                ASTNode rhs = childResults.get(1);
624
625                if(tokenS.isLextant(s2k.lexicalAnalyzer.Lextant.OR)) {
626                    replacement = Generators.makeIdisaFuncCallNode(locator, SIMD_OR, BITBLOCK_SIZE, Generators.arguments(lhs, rhs));
627                } 
628                else if(tokenS.isLextant(s2k.lexicalAnalyzer.Lextant.AND)) {
629                    // TS: this optimization seems inappropriate for s2k to handle.     
630                    if (rhsS.getToken().isLextant(s2k.lexicalAnalyzer.Lextant.NOT)) {                       
631                        replacement =  Generators.makeIdisaFuncCallNode(locator, SIMD_ANDC, BITBLOCK_SIZE,
632                                Generators.arguments(lhs, Accessors.idisaFuncCallArgListNode((IdisaFuncCallNode)rhs).child(0)));
633                    } 
634                    else if(lhsS.getToken().isLextant(s2k.lexicalAnalyzer.Lextant.NOT)) {
635                        replacement =  Generators.makeIdisaFuncCallNode(locator, SIMD_ANDC, BITBLOCK_SIZE,
636                                Generators.arguments(rhs, Accessors.idisaFuncCallArgListNode((IdisaFuncCallNode)lhs).child(0)));
637                    } 
638                    else { 
639                        replacement =  Generators.makeIdisaFuncCallNode(locator, SIMD_AND, BITBLOCK_SIZE, Generators.arguments(lhs, rhs));   
640                    }
641                }
642                else if (tokenS.isLextant(s2k.lexicalAnalyzer.Lextant.XOR)){
643                    replacement = Generators.makeIdisaFuncCallNode(locator, SIMD_XOR, BITBLOCK_SIZE, Generators.arguments(lhs, rhs));
644                } 
645            } else {
646                replacement = defaultVisitLeave(snode, childResults);
647            }
648            return replacement;
649        }       
650
651        ////////////////////////////////////////////////////////////////////////////////////
652        // Bitwise / UnaryOp 
653        public ASTNode visitLeave(s2k.ast.UnaryOperatorNode snode, List<ASTNode> childResults) {
654
655            s2k.tokens.Token token = snode.getToken();
656            ASTNode replacement = null;
657           
658            if(token.isLextant(s2k.lexicalAnalyzer.Lextant.NOT)) {
659                Locator locator = Generators.makeTextLocation(token.getLocation());
660                ASTNode operand = childResults.get(0); 
661                replacement = Generators.makeIdisaFuncCallNode(locator, SIMD_NOT, BITBLOCK_SIZE, Generators.arguments(operand));
662            } else {
663                replacement = defaultVisitLeave(snode, childResults);
664            }
665            return replacement;
666        }
667    }
668}
Note: See TracBrowser for help on using the repository browser.