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

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

Fixed bug in S2K2B2K transformer.

File size: 32.4 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.FilterDefNode> funcDefs = toolchain.s2k.ast.Accessors.funcDefs((s2k.ast.ProgramNode) s2kASTree);
57       
58        for(s2k.ast.FilterDefNode 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.FilterParameterListNode 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.FilterDefNode snode, List<ASTNode> childResults) {
245           
246            ASTNode replacement = new FuncDefNode(Generators.makeToken(snode.getToken()));
247            appendChildResults(replacement, childResults);
248           
249            int carry1Count = propInfoSetMap.get(snode).carry1Count;
250
251            if(needsCarryAdjustment(context, carry1Count) ) { 
252                addCarryAdjustment((FuncDefNode) replacement, context, carry1Count);
253            }
254                       
255            if(context.isFinalBlockMode()) {
256                if(!hasEOFMaskParameter((FuncDefNode)replacement)) {
257                    b2k.ast.ParameterNode EOFMaskParameter = Generators.makeEofMaskParameter(replacement);
258                    Generators.appendParameter((FuncDefNode) replacement, EOFMaskParameter);
259                }
260            }
261                       
262            return replacement;
263         }
264       
265        private boolean needsCarryAdjustment(Context context, int carry1Count) {
266            return !context.isFinalBlockMode() && carry1Count > 0;
267        }
268
269        private void addCarryAdjustment(FuncDefNode node, Context context, int carry1Count) {
270            FuncCallNode carryAdjustment = Generators.makeCarryAdjustmentCall(node, context, carry1Count);
271            ASTNode body = Accessors.body(node);
272            body.appendChild(carryAdjustment);
273        }       
274       
275        private boolean hasEOFMaskParameter(FuncDefNode node) {
276            if(Accessors.hasParameters(node)) {
277                ParameterListNode parameterList = Accessors.parameterListNode(node);
278                ASTNode lastParameter = parameterList.lastChild();
279
280                final String EOF_Mask = B2KBuiltin.EOF_MASK.b2kName(); //context.getBuiltinEncoder().getName(S2KBuiltin.EOF_MASK);
281
282                if(Accessors.name(lastParameter).equals(EOF_Mask)) {
283                    return true;
284                } 
285            }
286            return false;
287        }
288       
289        ////////////////////////////////////////////////////////////////////////////////////
290        // IfStmt       
291        //
292        //  'carry-in' - enabled
293        //
294        //  if (condition) { S* } => if (Any(Or(condition, CarryTest(carry1Position, carry1Count))) { S* }
295        //       
296        //  'carry-in' - disabled
297        //       
298        //  if (condition) { S* } => if (Any(condition)) { S* }
299        //
300        //  Note: ANDC EOF_Mask is not applied to 'condition' because we test the position following the EOF for errors.
301        //
302        public ASTNode visitLeave(s2k.ast.IfStmtNode snode, List<ASTNode> childResults) {
303           
304            int carryNCount = propInfoSetMap.get(snode).carryNCount;
305            assert (carryNCount == 0): "Advance(x,n) illegal within an if statement \n";    // should be better diagnostic
306
307            IfStmtNode replacement = (IfStmtNode) defaultVisitLeave(snode, childResults);
308
309            int carry1Count     = propInfoSetMap.get(snode).carry1Count;
310
311            if(ifNeedsCarryProcessing(context, carry1Count)) {
312
313                int carry1Position  = propInfoSetMap.get(snode).carry1Position;
314                orCarryRangeIntoCondition(replacement, context, carry1Position, carry1Count);
315                appendCarryDequeueEnqueueToElseClause(replacement, context, carry1Position, carry1Count);
316            }
317
318            Mutators.surroundConditionWithBitBlockAny(replacement, Accessors.condition(replacement));
319
320            return replacement;
321        }
322
323        private boolean ifNeedsCarryProcessing(Context context, int carry1Count) {
324            return context.isCarryInMode() && carry1Count > 0;
325        }
326                 
327        private void orCarryRangeIntoCondition(IfStmtNode node, Context context, int carry1Position, int carry1Count) {
328            ASTNode condition = Accessors.condition(node);
329            ASTNode replacementCondition = Generators.makeBitwiseOrCarryTest(condition.deepCopy(), context, carry1Position, carry1Count);
330           
331            node.replaceChild(condition, replacementCondition);
332        }
333
334        private void appendCarryDequeueEnqueueToElseClause(IfStmtNode node, Context context, int carry1Position, int carry1Count) {
335            Locator locator = node.getLocation();
336            ASTNode carryDequeueEnqueue = Generators.makeCarryDequeueEnqueueCall(locator, context, carry1Position, carry1Count);
337
338            ensureHasElseClause(node); 
339            Accessors.elseClause(node).appendChild(carryDequeueEnqueue);
340        }       
341       
342        private void ensureHasElseClause(IfStmtNode node) {
343            if (!Accessors.hasElseClause(node)) {   
344                BlockStmtNode blockStmtNode = Generators.makeBlockStmtNode(node);
345                node.appendChild(blockStmtNode); 
346            }
347        }
348
349        ////////////////////////////////////////////////////////////////////////////////////
350        // WhileStmt translation       
351        //
352        //   if 'carry1Count' is zero
353        //
354        //     while(condition) body => while(condition) body
355        //
356        //   else if 'carry1Count' greater than zero
357        //
358        //     if 'carry-in' mode is disabled
359        //
360        //       while(condition) body =>
361        //
362        //       while(bitblock::any(condition')) {
363        //           carryDeclare(localCarrySetID, carry1Count, carryNCount)
364        //           phi(body)           
365        //           carryCombine(carrySetID, localCarrySetID, carry1Position, carry1Count)
366        //       }
367        //
368        //     else if 'carry-in' mode is enabled
369        //
370        //       while(condition) body  =>
371        //
372        //       if(bitblock::any(condition''))) {
373        //         body
374        //         while(bitblock::any(condition')) {
375        //           carryDeclare(localCarrySetID, carry1Count, carryNCount)
376        //           phi(body)           
377        //           carryCombine(carrySetID, localCarrySetID, carry1Position, carry1Count)
378        //         }
379        //       }
380        //       else {
381        //         carryDequeEnque(carryBase, carry1Count)
382        //       }
383        //
384        //   condition'      = condition ANDC EOFMask if in finalBlock mode, bitblock::Any
385        //   condition''     = condition OR carryTest in carryIn mode, ANDC EOFMask if in finalBlock mode, bitblock::Any
386        //   phi is recursive transform with depth+1 and carryIn=false, using localCarrySet       
387        //
388        //
389        public ASTNode visitLeave(s2k.ast.WhileStmtNode snode, List<ASTNode> childResults) {
390
391            int carryNCount = propInfoSetMap.get(snode).carryNCount;
392            assert (carryNCount == 0): "Advance(x,n) illegal within an if statement \n";    // should be better diagnostic           
393           
394            ASTNode replacement         = defaultVisitLeave(snode, childResults);
395           
396            int carry1Count = propInfoSetMap.get(snode).carry1Count;
397            if(ifNeedsCarryProcessing(context, carry1Count)) {
398
399                    ASTNode outerCondition      = Accessors.condition((WhileStmtNode) replacement);
400                    ASTNode outerBody           = Accessors.body((WhileStmtNode) replacement);
401                    replacement = makeGeneralWhileReplacement(snode, outerCondition, outerBody);
402
403                    if(context.isFinalBlockMode()) {
404                        andConditionWithEOFMask(Accessors.condition((IfStmtNode) replacement));                   
405                    }
406                   
407                    Mutators.surroundConditionWithBitBlockAny(replacement, Accessors.condition((IfStmtNode) replacement));
408                   
409            } else {
410               
411                if(context.isFinalBlockMode()) {
412                    andConditionWithEOFMask(Accessors.condition((WhileStmtNode) replacement));                   
413                }
414               
415                Mutators.surroundConditionWithBitBlockAny(replacement, Accessors.condition((WhileStmtNode) replacement));   
416            }
417           
418            return replacement;
419        }       
420       
421        private IfStmtNode makeGeneralWhileReplacement(s2k.ast.WhileStmtNode snode, ASTNode condition, ASTNode body) {
422            Locator locator = Generators.makeTextLocation(snode.getLocation());
423
424            int carry1Position  = propInfoSetMap.get(snode).carry1Position;
425            int carry1Count     = propInfoSetMap.get(snode).carry1Count;
426
427            ASTNode outerCondition      = makeOuterIfCondition(condition, carry1Position, carry1Count);   
428            BlockStmtNode thenClause    = outerIfThenClause(snode, condition, body, carry1Position, carry1Count);
429            BlockStmtNode elseClause    = outerIfElseClause(snode, carry1Position, carry1Count);
430
431            return Generators.makeIfStmtNode(locator, outerCondition, thenClause, elseClause);
432        }       
433       
434        private ASTNode makeOuterIfCondition(ASTNode condition, int carry1Position, int carry1Count) {
435            ASTNode result = condition.deepCopy();
436            if(carry1Count > 0) {
437                result = Generators.makeBitwiseOrCarryTest(result, context, carry1Position, carry1Count);
438            }
439            return result;
440        }         
441       
442        private void andConditionWithEOFMask(ASTNode condition) {
443            Locator locator = condition.getLocation();
444            ASTNode replacement = Generators.makeExprAndEofMaskCall(locator, condition.deepCopy());
445            condition.updateSelf(replacement);
446        }
447       
448        private BlockStmtNode outerIfThenClause(s2k.ast.WhileStmtNode snode, ASTNode condition, ASTNode body, int carry1Position, int carry1Count) {
449            Locator locator                     = Generators.makeTextLocation(snode.getLocation());
450
451            BlockStmtNode outerIfThenBlockStmt  = Generators.makeBlockStmtNode(locator, body);
452            WhileStmtNode innerWhile            = makeInnerWhile(snode, condition, carry1Position, carry1Count); 
453            outerIfThenBlockStmt.appendChild(innerWhile);
454
455            return outerIfThenBlockStmt;
456        }       
457       
458        private WhileStmtNode makeInnerWhile(s2k.ast.WhileStmtNode snode, ASTNode condition, int carry1Position, int carry1Count) {
459
460            Locator locator = Generators.makeTextLocation(snode.getLocation());
461
462            Context localContext = context.incrementDepth().clearCarryIn();             
463            s2k.ast.BlockStmtNode sbody = toolchain.s2k.ast.Accessors.body(snode);
464            BlockStmtNode body = transformBody(sbody, localContext);
465
466            WhileStmtNode innerWhile = new WhileStmtNode(Generators.makeToken(snode.getToken()));
467           
468            innerWhile.appendChild(condition);
469           
470            if(context.isFinalBlockMode()) {
471                andConditionWithEOFMask(Accessors.condition((WhileStmtNode) innerWhile));                   
472            }
473           
474            Mutators.surroundConditionWithBitBlockAny(innerWhile, Accessors.condition((WhileStmtNode) innerWhile));
475           
476            innerWhile.appendChild(body);
477           
478            insertCarryDeclare(locator, body, localContext, carry1Count, 0); // carryNCount == 0 by assertion in visitLeave(WhileStmtNode)
479            appendCarryCombine(locator, body, context, localContext, carry1Position, carry1Count);
480
481            return innerWhile;
482        }       
483       
484        private BlockStmtNode transformBody(s2k.ast.ASTNode snode, Context localContext) {
485
486            Map<s2k.ast.ASTNode, PropertyInfoSet> propInfoSetMap  = PropertyInfoSetMapBuilder.forTree(snode);
487            S2K2B2KTranslator S2BXTranslator                      = new S2K2B2KTranslator(propInfoSetMap, localContext);
488            BlockStmtNode body                                    = (BlockStmtNode) snode.accept(S2BXTranslator); 
489            return body;
490        }       
491       
492        private BlockStmtNode outerIfElseClause(s2k.ast.WhileStmtNode snode, int carry1Position, int carry1Count) {
493           
494            Locator locator                     = Generators.makeTextLocation(snode.getLocation());
495            FuncCallNode carryDequeueEnqueue    = Generators.makeCarryDequeueEnqueueCall(locator, context, carry1Position, carry1Count);
496            return Generators.makeBlockStmtNode(locator, carryDequeueEnqueue);
497        }       
498       
499        private void insertCarryDeclare(Locator locator, ASTNode body, Context localContext, int carry1Count, int carryNCount) {
500
501            FuncCallNode carryDeclare = Generators.makeCarryDeclareCall(locator, localContext, carry1Count, carryNCount);
502            body.insertChild(carryDeclare);
503        }
504       
505        private void appendCarryCombine(Locator locator, ASTNode body, Context context, Context localContext, int carry1Position, int carry1Count) {
506                       
507            FuncCallNode localCarryCombine = Generators.makeLocalCarryCombineCall(locator, context, localContext, carry1Position, carry1Count); 
508            body.appendChild(localCarryCombine);
509        }       
510       
511        ////////////////////////////////////////////////////////////////////////////////////
512        // FuncCall       
513        //
514        // Translation of s2k builtin depends on 'carry-in' mode, 'final-block' mode, and
515        // the prior execution of the TempifyCarryBuiltinCalls transformer.
516        //
517        public ASTNode visitLeave(s2k.ast.FuncCallNode snode, List<ASTNode> childResults) {
518
519            ASTNode replacement = null;
520           
521            if (BuiltinCallUtil.isCarryNone(snode)) { 
522
523                S2KBuiltin builtin = BuiltinCallUtil.builtin(snode);
524                S2KBuiltinTranslator translator = builtin.getTranslator();
525
526                ASTNode funcCallArgsList = childResults.get(1);
527                List<ASTNode> args = funcCallArgsList.getChildren();
528                replacement = translator.translate(builtin, snode, context, args); 
529               
530            } else {
531
532                replacement  = new FuncCallNode(Generators.makeToken(snode.getToken()));
533                appendChildResults(replacement, childResults);
534            }
535           
536            return replacement;
537        }
538
539        ////////////////////////////////////////////////////////////////////////////////////
540        // AssignNode       
541        public ASTNode visitLeave(s2k.ast.AssignNode snode, List<ASTNode> childResults) {
542
543            s2k.ast.ASTNode rhs = toolchain.s2k.ast.Accessors.rhs(snode);
544
545            if(BuiltinCallUtil.isCarry(rhs)) {
546
547                Locator locator = Generators.makeTextLocation(snode.getLocation());
548
549                ASTNode funcCallArgsList = childResults.get(1).child(1);
550                List<ASTNode> args = funcCallArgsList.getChildren();
551
552                ASTNode carryCall = makeCarryCall(locator, context, rhs);
553                args.add(carryCall);
554
555                ASTNode returnValue = childResults.get(0);
556                args.add(returnValue);
557
558                S2KBuiltin builtin = BuiltinCallUtil.builtin(rhs);
559                S2KBuiltinTranslator translator = builtin.getTranslator();
560                ASTNode b2kBlkFuncCall = translator.translate(builtin, (s2k.ast.FuncCallNode) rhs, context, args);
561               
562                return Generators.makeAssignNode(locator, carryCall, b2kBlkFuncCall);
563
564            } 
565
566            ASTNode replacement  = new AssignNode(Generators.makeToken(snode.getToken()));
567            appendChildResults(replacement, childResults);
568            return replacement;
569        }
570       
571        private ASTNode makeCarryCall(Locator locator, Context context, s2k.ast.ASTNode rhs) {
572            ASTNode carryCall = null;
573           
574            if(BuiltinCallUtil.isCarry1(rhs)) {
575                int carry1Position = propInfoSetMap.get(rhs).carry1Position;
576                carryCall = Generators.makeGetCarryCall(locator, context, carry1Position);
577
578            } else if(BuiltinCallUtil.isCarryN(rhs)) {
579                int carryNPosition = propInfoSetMap.get(rhs).carryNPosition;
580                carryCall = Generators.makePending64Call(locator, context, carryNPosition);
581            }
582           
583            return carryCall;
584        }           
585       
586        ////////////////////////////////////////////////////////////////////////////////////
587        // StreamType // TODO - KH: Handle field width attributes on s2k stream types
588        public ASTNode visitLeave(s2k.ast.StreamTypeNode snode, List<ASTNode> childResults) {
589
590            String lexeme = b2k.lexicalAnalyzer.Lextant.BITBLOCK.getPrimaryLexeme();
591
592            Token token = b2k.tokens.LextantToken.make(Generators.makeTextLocation(snode.getToken().getLocation()), 
593                    lexeme, 
594                    b2k.lexicalAnalyzer.Lextant.forLexeme(lexeme, Generators.LEXICAL_CONTEXT)); 
595
596            ASTNode replacement = new BitBlockTypeNode(token);
597            appendChildResults(replacement, childResults);
598           
599            return replacement;
600        }
601
602        public ASTNode visitLeave(s2k.ast.IntegerConstantNode snode, List<ASTNode> childResults) {
603            ASTNode replacement = new IntegerConstantNode(Generators.makeToken(snode.getToken()));
604            int value = new Integer(replacement.getToken().getLexeme());
605            ((IntegerConstantNode)replacement).setValue(value); 
606            appendChildResults(replacement, childResults);
607            return replacement;
608        }
609
610        ////////////////////////////////////////////////////////////////////////////////////
611        // Bitwise / BinaryOp
612        public ASTNode visitLeave(s2k.ast.BinaryOperatorNode snode, List<ASTNode> childResults) {
613
614            s2k.tokens.Token tokenS = snode.getToken();
615            s2k.ast.ASTNode lhsS = toolchain.s2k.ast.Accessors.lhs(snode);
616            s2k.ast.ASTNode rhsS = toolchain.s2k.ast.Accessors.rhs(snode);
617
618            ASTNode replacement = null;
619 
620            if(tokenS.isLextant(s2k.lexicalAnalyzer.Lextant.AND, s2k.lexicalAnalyzer.Lextant.OR, s2k.lexicalAnalyzer.Lextant.XOR)) {
621
622                TextLocation locator = Generators.makeTextLocation(tokenS.getLocation());
623                ASTNode lhs = childResults.get(0);
624                ASTNode rhs = childResults.get(1);
625
626                if(tokenS.isLextant(s2k.lexicalAnalyzer.Lextant.OR)) {
627                    replacement = Generators.makeIdisaFuncCallNode(locator, SIMD_OR, BITBLOCK_SIZE, Generators.arguments(lhs, rhs));
628                } 
629                else if(tokenS.isLextant(s2k.lexicalAnalyzer.Lextant.AND)) {
630                    // TS: this optimization seems inappropriate for s2k to handle.     
631                    if (rhsS.getToken().isLextant(s2k.lexicalAnalyzer.Lextant.NOT)) {                       
632                        replacement =  Generators.makeIdisaFuncCallNode(locator, SIMD_ANDC, BITBLOCK_SIZE,
633                                Generators.arguments(lhs, Accessors.idisaFuncCallArgListNode((IdisaFuncCallNode)rhs).child(0)));
634                    } 
635                    else if(lhsS.getToken().isLextant(s2k.lexicalAnalyzer.Lextant.NOT)) {
636                        replacement =  Generators.makeIdisaFuncCallNode(locator, SIMD_ANDC, BITBLOCK_SIZE,
637                                Generators.arguments(rhs, Accessors.idisaFuncCallArgListNode((IdisaFuncCallNode)lhs).child(0)));
638                    } 
639                    else { 
640                        replacement =  Generators.makeIdisaFuncCallNode(locator, SIMD_AND, BITBLOCK_SIZE, Generators.arguments(lhs, rhs));   
641                    }
642                }
643                else if (tokenS.isLextant(s2k.lexicalAnalyzer.Lextant.XOR)){
644                    replacement = Generators.makeIdisaFuncCallNode(locator, SIMD_XOR, BITBLOCK_SIZE, Generators.arguments(lhs, rhs));
645                } 
646            } else {
647                replacement = defaultVisitLeave(snode, childResults);
648            }
649            return replacement;
650        }       
651
652        ////////////////////////////////////////////////////////////////////////////////////
653        // Bitwise / UnaryOp 
654        public ASTNode visitLeave(s2k.ast.UnaryOperatorNode snode, List<ASTNode> childResults) {
655
656            s2k.tokens.Token token = snode.getToken();
657            ASTNode replacement = null;
658           
659            if(token.isLextant(s2k.lexicalAnalyzer.Lextant.NOT)) {
660                Locator locator = Generators.makeTextLocation(token.getLocation());
661                ASTNode operand = childResults.get(0); 
662                replacement = Generators.makeIdisaFuncCallNode(locator, SIMD_NOT, BITBLOCK_SIZE, Generators.arguments(operand));
663            } else {
664                replacement = defaultVisitLeave(snode, childResults);
665            }
666            return replacement;
667        }
668    }
669}
Note: See TracBrowser for help on using the repository browser.