~vcs-imports/qemu/git

« back to all changes in this revision

Viewing changes to target-cris/op_helper.c

  • Committer: blueswir1
  • Date: 2007-09-25 17:30:09 UTC
  • Revision ID: git-v1:eb296a0a03eebd2d73718d31cd0d8a8db0b804de
 Remove the target dependency introduced by previous patch


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3239 c046a42c-6fe2-441c-8c8c-71466251a162

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *  CRIS helper routines
3
 
 *
4
 
 *  Copyright (c) 2007 AXIS Communications
5
 
 *  Written by Edgar E. Iglesias
6
 
 *
7
 
 * This library is free software; you can redistribute it and/or
8
 
 * modify it under the terms of the GNU Lesser General Public
9
 
 * License as published by the Free Software Foundation; either
10
 
 * version 2 of the License, or (at your option) any later version.
11
 
 *
12
 
 * This library is distributed in the hope that it will be useful,
13
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 
 * Lesser General Public License for more details.
16
 
 *
17
 
 * You should have received a copy of the GNU Lesser General Public
18
 
 * License along with this library; if not, write to the Free Software
19
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
 
 */
21
 
 
22
 
#include <assert.h>
23
 
#include "exec.h"
24
 
#include "mmu.h"
25
 
#include "helper.h"
26
 
 
27
 
#define D(x)
28
 
 
29
 
#if !defined(CONFIG_USER_ONLY)
30
 
 
31
 
#define MMUSUFFIX _mmu
32
 
 
33
 
#define SHIFT 0
34
 
#include "softmmu_template.h"
35
 
 
36
 
#define SHIFT 1
37
 
#include "softmmu_template.h"
38
 
 
39
 
#define SHIFT 2
40
 
#include "softmmu_template.h"
41
 
 
42
 
#define SHIFT 3
43
 
#include "softmmu_template.h"
44
 
 
45
 
/* Try to fill the TLB and return an exception if error. If retaddr is
46
 
   NULL, it means that the function was called in C code (i.e. not
47
 
   from generated code or from helper.c) */
48
 
/* XXX: fix it to restore all registers */
49
 
void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
50
 
{
51
 
    TranslationBlock *tb;
52
 
    CPUState *saved_env;
53
 
    unsigned long pc;
54
 
    int ret;
55
 
 
56
 
    /* XXX: hack to restore env in all cases, even if not called from
57
 
       generated code */
58
 
    saved_env = env;
59
 
    env = cpu_single_env;
60
 
 
61
 
    D(fprintf(logfile, "%s pc=%x tpc=%x ra=%x\n", __func__, 
62
 
             env->pc, env->debug1, retaddr));
63
 
    ret = cpu_cris_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
64
 
    if (unlikely(ret)) {
65
 
        if (retaddr) {
66
 
            /* now we have a real cpu fault */
67
 
            pc = (unsigned long)retaddr;
68
 
            tb = tb_find_pc(pc);
69
 
            if (tb) {
70
 
                /* the PC is inside the translated code. It means that we have
71
 
                   a virtual CPU fault */
72
 
                cpu_restore_state(tb, env, pc, NULL);
73
 
 
74
 
                /* Evaluate flags after retranslation.  */
75
 
                helper_top_evaluate_flags();
76
 
            }
77
 
        }
78
 
        cpu_loop_exit();
79
 
    }
80
 
    env = saved_env;
81
 
}
82
 
 
83
 
#endif
84
 
 
85
 
void helper_raise_exception(uint32_t index)
86
 
{
87
 
        env->exception_index = index;
88
 
        cpu_loop_exit();
89
 
}
90
 
 
91
 
void helper_tlb_flush_pid(uint32_t pid)
92
 
{
93
 
#if !defined(CONFIG_USER_ONLY)
94
 
        pid &= 0xff;
95
 
        if (pid != (env->pregs[PR_PID] & 0xff))
96
 
                cris_mmu_flush_pid(env, env->pregs[PR_PID]);
97
 
#endif
98
 
}
99
 
 
100
 
void helper_spc_write(uint32_t new_spc)
101
 
{
102
 
#if !defined(CONFIG_USER_ONLY)
103
 
        tlb_flush_page(env, env->pregs[PR_SPC]);
104
 
        tlb_flush_page(env, new_spc);
105
 
#endif
106
 
}
107
 
 
108
 
void helper_dump(uint32_t a0, uint32_t a1, uint32_t a2)
109
 
{
110
 
        (fprintf(logfile, "%s: a0=%x a1=%x\n", __func__, a0, a1)); 
111
 
}
112
 
 
113
 
/* Used by the tlb decoder.  */
114
 
#define EXTRACT_FIELD(src, start, end) \
115
 
            (((src) >> start) & ((1 << (end - start + 1)) - 1))
116
 
 
117
 
void helper_movl_sreg_reg (uint32_t sreg, uint32_t reg)
118
 
{
119
 
        uint32_t srs;
120
 
        srs = env->pregs[PR_SRS];
121
 
        srs &= 3;
122
 
        env->sregs[srs][sreg] = env->regs[reg];
123
 
 
124
 
#if !defined(CONFIG_USER_ONLY)
125
 
        if (srs == 1 || srs == 2) {
126
 
                if (sreg == 6) {
127
 
                        /* Writes to tlb-hi write to mm_cause as a side 
128
 
                           effect.  */
129
 
                        env->sregs[SFR_RW_MM_TLB_HI] = env->regs[reg];
130
 
                        env->sregs[SFR_R_MM_CAUSE] = env->regs[reg];
131
 
                }
132
 
                else if (sreg == 5) {
133
 
                        uint32_t set;
134
 
                        uint32_t idx;
135
 
                        uint32_t lo, hi;
136
 
                        uint32_t vaddr;
137
 
                        int tlb_v;
138
 
 
139
 
                        idx = set = env->sregs[SFR_RW_MM_TLB_SEL];
140
 
                        set >>= 4;
141
 
                        set &= 3;
142
 
 
143
 
                        idx &= 15;
144
 
                        /* We've just made a write to tlb_lo.  */
145
 
                        lo = env->sregs[SFR_RW_MM_TLB_LO];
146
 
                        /* Writes are done via r_mm_cause.  */
147
 
                        hi = env->sregs[SFR_R_MM_CAUSE];
148
 
 
149
 
                        vaddr = EXTRACT_FIELD(env->tlbsets[srs-1][set][idx].hi,
150
 
                                              13, 31);
151
 
                        vaddr <<= TARGET_PAGE_BITS;
152
 
                        tlb_v = EXTRACT_FIELD(env->tlbsets[srs-1][set][idx].lo,
153
 
                                            3, 3);
154
 
                        env->tlbsets[srs - 1][set][idx].lo = lo;
155
 
                        env->tlbsets[srs - 1][set][idx].hi = hi;
156
 
 
157
 
                        D(fprintf(logfile, 
158
 
                                  "tlb flush vaddr=%x v=%d pc=%x\n", 
159
 
                                  vaddr, tlb_v, env->pc));
160
 
                        tlb_flush_page(env, vaddr);
161
 
                }
162
 
        }
163
 
#endif
164
 
}
165
 
 
166
 
void helper_movl_reg_sreg (uint32_t reg, uint32_t sreg)
167
 
{
168
 
        uint32_t srs;
169
 
        env->pregs[PR_SRS] &= 3;
170
 
        srs = env->pregs[PR_SRS];
171
 
        
172
 
#if !defined(CONFIG_USER_ONLY)
173
 
        if (srs == 1 || srs == 2)
174
 
        {
175
 
                uint32_t set;
176
 
                uint32_t idx;
177
 
                uint32_t lo, hi;
178
 
 
179
 
                idx = set = env->sregs[SFR_RW_MM_TLB_SEL];
180
 
                set >>= 4;
181
 
                set &= 3;
182
 
                idx &= 15;
183
 
 
184
 
                /* Update the mirror regs.  */
185
 
                hi = env->tlbsets[srs - 1][set][idx].hi;
186
 
                lo = env->tlbsets[srs - 1][set][idx].lo;
187
 
                env->sregs[SFR_RW_MM_TLB_HI] = hi;
188
 
                env->sregs[SFR_RW_MM_TLB_LO] = lo;
189
 
        }
190
 
#endif
191
 
        env->regs[reg] = env->sregs[srs][sreg];
192
 
        RETURN();
193
 
}
194
 
 
195
 
static void cris_ccs_rshift(CPUState *env)
196
 
{
197
 
        uint32_t ccs;
198
 
 
199
 
        /* Apply the ccs shift.  */
200
 
        ccs = env->pregs[PR_CCS];
201
 
        ccs = (ccs & 0xc0000000) | ((ccs & 0x0fffffff) >> 10);
202
 
        if (ccs & U_FLAG)
203
 
        {
204
 
                /* Enter user mode.  */
205
 
                env->ksp = env->regs[R_SP];
206
 
                env->regs[R_SP] = env->pregs[PR_USP];
207
 
        }
208
 
 
209
 
        env->pregs[PR_CCS] = ccs;
210
 
}
211
 
 
212
 
void helper_rfe(void)
213
 
{
214
 
        int rflag = env->pregs[PR_CCS] & R_FLAG;
215
 
 
216
 
        D(fprintf(logfile, "rfe: erp=%x pid=%x ccs=%x btarget=%x\n", 
217
 
                 env->pregs[PR_ERP], env->pregs[PR_PID],
218
 
                 env->pregs[PR_CCS],
219
 
                 env->btarget));
220
 
 
221
 
        cris_ccs_rshift(env);
222
 
 
223
 
        /* RFE sets the P_FLAG only if the R_FLAG is not set.  */
224
 
        if (!rflag)
225
 
                env->pregs[PR_CCS] |= P_FLAG;
226
 
}
227
 
 
228
 
void helper_rfn(void)
229
 
{
230
 
        int rflag = env->pregs[PR_CCS] & R_FLAG;
231
 
 
232
 
        D(fprintf(logfile, "rfn: erp=%x pid=%x ccs=%x btarget=%x\n", 
233
 
                 env->pregs[PR_ERP], env->pregs[PR_PID],
234
 
                 env->pregs[PR_CCS],
235
 
                 env->btarget));
236
 
 
237
 
        cris_ccs_rshift(env);
238
 
 
239
 
        /* Set the P_FLAG only if the R_FLAG is not set.  */
240
 
        if (!rflag)
241
 
                env->pregs[PR_CCS] |= P_FLAG;
242
 
 
243
 
    /* Always set the M flag.  */
244
 
    env->pregs[PR_CCS] |= M_FLAG;
245
 
}
246
 
 
247
 
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
248
 
                          int is_asi, int size)
249
 
{
250
 
        D(printf("%s addr=%x w=%d ex=%d asi=%d, size=%d\n",
251
 
                __func__, addr, is_write, is_exec, is_asi, size));
252
 
}
253
 
 
254
 
static void evaluate_flags_writeback(uint32_t flags)
255
 
{
256
 
        int x;
257
 
 
258
 
        /* Extended arithmetics, leave the z flag alone.  */
259
 
        x = env->cc_x;
260
 
        if ((x || env->cc_op == CC_OP_ADDC)
261
 
            && flags & Z_FLAG)
262
 
                env->cc_mask &= ~Z_FLAG;
263
 
 
264
 
        /* all insn clear the x-flag except setf or clrf.  */
265
 
        env->pregs[PR_CCS] &= ~(env->cc_mask | X_FLAG);
266
 
        flags &= env->cc_mask;
267
 
        env->pregs[PR_CCS] |= flags;
268
 
}
269
 
 
270
 
void helper_evaluate_flags_muls(void)
271
 
{
272
 
        uint32_t src;
273
 
        uint32_t dst;
274
 
        uint32_t res;
275
 
        uint32_t flags = 0;
276
 
        int64_t tmp;
277
 
        int32_t mof;
278
 
        int dneg;
279
 
 
280
 
        src = env->cc_src;
281
 
        dst = env->cc_dest;
282
 
        res = env->cc_result;
283
 
 
284
 
        dneg = ((int32_t)res) < 0;
285
 
 
286
 
        mof = env->pregs[PR_MOF];
287
 
        tmp = mof;
288
 
        tmp <<= 32;
289
 
        tmp |= res;
290
 
        if (tmp == 0)
291
 
                flags |= Z_FLAG;
292
 
        else if (tmp < 0)
293
 
                flags |= N_FLAG;
294
 
        if ((dneg && mof != -1)
295
 
            || (!dneg && mof != 0))
296
 
                flags |= V_FLAG;
297
 
        evaluate_flags_writeback(flags);
298
 
}
299
 
 
300
 
void  helper_evaluate_flags_mulu(void)
301
 
{
302
 
        uint32_t src;
303
 
        uint32_t dst;
304
 
        uint32_t res;
305
 
        uint32_t flags = 0;
306
 
        uint64_t tmp;
307
 
        uint32_t mof;
308
 
 
309
 
        src = env->cc_src;
310
 
        dst = env->cc_dest;
311
 
        res = env->cc_result;
312
 
 
313
 
        mof = env->pregs[PR_MOF];
314
 
        tmp = mof;
315
 
        tmp <<= 32;
316
 
        tmp |= res;
317
 
        if (tmp == 0)
318
 
                flags |= Z_FLAG;
319
 
        else if (tmp >> 63)
320
 
                flags |= N_FLAG;
321
 
        if (mof)
322
 
                flags |= V_FLAG;
323
 
 
324
 
        evaluate_flags_writeback(flags);
325
 
}
326
 
 
327
 
void  helper_evaluate_flags_mcp(void)
328
 
{
329
 
        uint32_t src;
330
 
        uint32_t dst;
331
 
        uint32_t res;
332
 
        uint32_t flags = 0;
333
 
 
334
 
        src = env->cc_src;
335
 
        dst = env->cc_dest;
336
 
        res = env->cc_result;
337
 
 
338
 
        if ((res & 0x80000000L) != 0L)
339
 
        {
340
 
                flags |= N_FLAG;
341
 
                if (((src & 0x80000000L) == 0L)
342
 
                    && ((dst & 0x80000000L) == 0L))
343
 
                {
344
 
                        flags |= V_FLAG;
345
 
                }
346
 
                else if (((src & 0x80000000L) != 0L) &&
347
 
                         ((dst & 0x80000000L) != 0L))
348
 
                {
349
 
                        flags |= R_FLAG;
350
 
                }
351
 
        }
352
 
        else
353
 
        {
354
 
                if (res == 0L)
355
 
                        flags |= Z_FLAG;
356
 
                if (((src & 0x80000000L) != 0L)
357
 
                    && ((dst & 0x80000000L) != 0L))
358
 
                        flags |= V_FLAG;
359
 
                if ((dst & 0x80000000L) != 0L
360
 
                    || (src & 0x80000000L) != 0L)
361
 
                        flags |= R_FLAG;
362
 
        }
363
 
 
364
 
        evaluate_flags_writeback(flags);
365
 
}
366
 
 
367
 
void  helper_evaluate_flags_alu_4(void)
368
 
{
369
 
        uint32_t src;
370
 
        uint32_t dst;
371
 
        uint32_t res;
372
 
        uint32_t flags = 0;
373
 
 
374
 
        src = env->cc_src;
375
 
        dst = env->cc_dest;
376
 
 
377
 
        /* Reconstruct the result.  */
378
 
        switch (env->cc_op)
379
 
        {
380
 
                case CC_OP_SUB:
381
 
                        res = dst - src;
382
 
                        break;
383
 
                case CC_OP_ADD:
384
 
                        res = dst + src;
385
 
                        break;
386
 
                default:
387
 
                        res = env->cc_result;
388
 
                        break;
389
 
        }
390
 
 
391
 
        if (env->cc_op == CC_OP_SUB || env->cc_op == CC_OP_CMP)
392
 
                src = ~src;
393
 
 
394
 
        if ((res & 0x80000000L) != 0L)
395
 
        {
396
 
                flags |= N_FLAG;
397
 
                if (((src & 0x80000000L) == 0L)
398
 
                    && ((dst & 0x80000000L) == 0L))
399
 
                {
400
 
                        flags |= V_FLAG;
401
 
                }
402
 
                else if (((src & 0x80000000L) != 0L) &&
403
 
                         ((dst & 0x80000000L) != 0L))
404
 
                {
405
 
                        flags |= C_FLAG;
406
 
                }
407
 
        }
408
 
        else
409
 
        {
410
 
                if (res == 0L)
411
 
                        flags |= Z_FLAG;
412
 
                if (((src & 0x80000000L) != 0L)
413
 
                    && ((dst & 0x80000000L) != 0L))
414
 
                        flags |= V_FLAG;
415
 
                if ((dst & 0x80000000L) != 0L
416
 
                    || (src & 0x80000000L) != 0L)
417
 
                        flags |= C_FLAG;
418
 
        }
419
 
 
420
 
        if (env->cc_op == CC_OP_SUB
421
 
            || env->cc_op == CC_OP_CMP) {
422
 
                flags ^= C_FLAG;
423
 
        }
424
 
        evaluate_flags_writeback(flags);
425
 
}
426
 
 
427
 
void  helper_evaluate_flags_move_4 (void)
428
 
{
429
 
        uint32_t res;
430
 
        uint32_t flags = 0;
431
 
 
432
 
        res = env->cc_result;
433
 
 
434
 
        if ((int32_t)res < 0)
435
 
                flags |= N_FLAG;
436
 
        else if (res == 0L)
437
 
                flags |= Z_FLAG;
438
 
 
439
 
        evaluate_flags_writeback(flags);
440
 
}
441
 
void  helper_evaluate_flags_move_2 (void)
442
 
{
443
 
        uint32_t src;
444
 
        uint32_t flags = 0;
445
 
        uint16_t res;
446
 
 
447
 
        src = env->cc_src;
448
 
        res = env->cc_result;
449
 
 
450
 
        if ((int16_t)res < 0L)
451
 
                flags |= N_FLAG;
452
 
        else if (res == 0)
453
 
                flags |= Z_FLAG;
454
 
 
455
 
        evaluate_flags_writeback(flags);
456
 
}
457
 
 
458
 
/* TODO: This is expensive. We could split things up and only evaluate part of
459
 
   CCR on a need to know basis. For now, we simply re-evaluate everything.  */
460
 
void helper_evaluate_flags (void)
461
 
{
462
 
        uint32_t src;
463
 
        uint32_t dst;
464
 
        uint32_t res;
465
 
        uint32_t flags = 0;
466
 
 
467
 
        src = env->cc_src;
468
 
        dst = env->cc_dest;
469
 
        res = env->cc_result;
470
 
 
471
 
        if (env->cc_op == CC_OP_SUB || env->cc_op == CC_OP_CMP)
472
 
                src = ~src;
473
 
 
474
 
        /* Now, evaluate the flags. This stuff is based on
475
 
           Per Zander's CRISv10 simulator.  */
476
 
        switch (env->cc_size)
477
 
        {
478
 
                case 1:
479
 
                        if ((res & 0x80L) != 0L)
480
 
                        {
481
 
                                flags |= N_FLAG;
482
 
                                if (((src & 0x80L) == 0L)
483
 
                                    && ((dst & 0x80L) == 0L))
484
 
                                {
485
 
                                        flags |= V_FLAG;
486
 
                                }
487
 
                                else if (((src & 0x80L) != 0L)
488
 
                                         && ((dst & 0x80L) != 0L))
489
 
                                {
490
 
                                        flags |= C_FLAG;
491
 
                                }
492
 
                        }
493
 
                        else
494
 
                        {
495
 
                                if ((res & 0xFFL) == 0L)
496
 
                                {
497
 
                                        flags |= Z_FLAG;
498
 
                                }
499
 
                                if (((src & 0x80L) != 0L)
500
 
                                    && ((dst & 0x80L) != 0L))
501
 
                                {
502
 
                                        flags |= V_FLAG;
503
 
                                }
504
 
                                if ((dst & 0x80L) != 0L
505
 
                                    || (src & 0x80L) != 0L)
506
 
                                {
507
 
                                        flags |= C_FLAG;
508
 
                                }
509
 
                        }
510
 
                        break;
511
 
                case 2:
512
 
                        if ((res & 0x8000L) != 0L)
513
 
                        {
514
 
                                flags |= N_FLAG;
515
 
                                if (((src & 0x8000L) == 0L)
516
 
                                    && ((dst & 0x8000L) == 0L))
517
 
                                {
518
 
                                        flags |= V_FLAG;
519
 
                                }
520
 
                                else if (((src & 0x8000L) != 0L)
521
 
                                         && ((dst & 0x8000L) != 0L))
522
 
                                {
523
 
                                        flags |= C_FLAG;
524
 
                                }
525
 
                        }
526
 
                        else
527
 
                        {
528
 
                                if ((res & 0xFFFFL) == 0L)
529
 
                                {
530
 
                                        flags |= Z_FLAG;
531
 
                                }
532
 
                                if (((src & 0x8000L) != 0L)
533
 
                                    && ((dst & 0x8000L) != 0L))
534
 
                                {
535
 
                                        flags |= V_FLAG;
536
 
                                }
537
 
                                if ((dst & 0x8000L) != 0L
538
 
                                    || (src & 0x8000L) != 0L)
539
 
                                {
540
 
                                        flags |= C_FLAG;
541
 
                                }
542
 
                        }
543
 
                        break;
544
 
                case 4:
545
 
                        if ((res & 0x80000000L) != 0L)
546
 
                        {
547
 
                                flags |= N_FLAG;
548
 
                                if (((src & 0x80000000L) == 0L)
549
 
                                    && ((dst & 0x80000000L) == 0L))
550
 
                                {
551
 
                                        flags |= V_FLAG;
552
 
                                }
553
 
                                else if (((src & 0x80000000L) != 0L) &&
554
 
                                         ((dst & 0x80000000L) != 0L))
555
 
                                {
556
 
                                        flags |= C_FLAG;
557
 
                                }
558
 
                        }
559
 
                        else
560
 
                        {
561
 
                                if (res == 0L)
562
 
                                        flags |= Z_FLAG;
563
 
                                if (((src & 0x80000000L) != 0L)
564
 
                                    && ((dst & 0x80000000L) != 0L))
565
 
                                        flags |= V_FLAG;
566
 
                                if ((dst & 0x80000000L) != 0L
567
 
                                    || (src & 0x80000000L) != 0L)
568
 
                                        flags |= C_FLAG;
569
 
                        }
570
 
                        break;
571
 
                default:
572
 
                        break;
573
 
        }
574
 
 
575
 
        if (env->cc_op == CC_OP_SUB
576
 
            || env->cc_op == CC_OP_CMP) {
577
 
                flags ^= C_FLAG;
578
 
        }
579
 
        evaluate_flags_writeback(flags);
580
 
}
581
 
 
582
 
void helper_top_evaluate_flags(void)
583
 
{
584
 
        switch (env->cc_op)
585
 
        {
586
 
                case CC_OP_MCP:
587
 
                        helper_evaluate_flags_mcp();
588
 
                        break;
589
 
                case CC_OP_MULS:
590
 
                        helper_evaluate_flags_muls();
591
 
                        break;
592
 
                case CC_OP_MULU:
593
 
                        helper_evaluate_flags_mulu();
594
 
                        break;
595
 
                case CC_OP_MOVE:
596
 
                case CC_OP_AND:
597
 
                case CC_OP_OR:
598
 
                case CC_OP_XOR:
599
 
                case CC_OP_ASR:
600
 
                case CC_OP_LSR:
601
 
                case CC_OP_LSL:
602
 
                        switch (env->cc_size)
603
 
                        {
604
 
                                case 4:
605
 
                                        helper_evaluate_flags_move_4();
606
 
                                        break;
607
 
                                case 2:
608
 
                                        helper_evaluate_flags_move_2();
609
 
                                        break;
610
 
                                default:
611
 
                                        helper_evaluate_flags();
612
 
                                        break;
613
 
                        }
614
 
                        break;
615
 
                case CC_OP_FLAGS:
616
 
                        /* live.  */
617
 
                        break;
618
 
                default:
619
 
                {
620
 
                        switch (env->cc_size)
621
 
                        {
622
 
                                case 4:
623
 
                                        helper_evaluate_flags_alu_4();
624
 
                                        break;
625
 
                                default:
626
 
                                        helper_evaluate_flags();
627
 
                                        break;
628
 
                        }
629
 
                }
630
 
                break;
631
 
        }
632
 
}